Maison > Questions et réponses > le corps du texte
每次启动这个activity memory allocated 逐渐增加,且不会被回收
求解决方案,下面是具体实现
public class NetWork {
private static AuthApi authApi;
private static UserApi userApi;
private static Converter.Factory gsonConverterFactory= GsonConverterFactory.create();
private static CallAdapter.Factory rxJavaCallAdapterFactory= RxJavaCallAdapterFactory.create();
public static AuthApi getAuthApi(){
Log.d("NetWork", "authApi==null:" + (authApi == null));
if(authApi == null){
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(UrlConfig.ACCESS_TOKEN)
.addCallAdapterFactory(rxJavaCallAdapterFactory)
.addConverterFactory(gsonConverterFactory)
.build();
authApi=retrofit.create(AuthApi.class);
}
return authApi;
}
public static UserApi getUserApi(){
Log.d("NetWork", "userApi==null:" + (userApi == null));
if(userApi == null){
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(UrlConfig.BASE_URL)
.addCallAdapterFactory(rxJavaCallAdapterFactory)
.addConverterFactory(gsonConverterFactory)
.build();
userApi=retrofit.create(UserApi.class);
}
return userApi;
}
}
public class OAuthLoginActivity extends AppCompatActivity {
private WebViewProgress mWebView;
Subscription mSubscription;
Subscription mProgressSubscription;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_oauth);
initView();
/*
* 1.getCode client_id scope
* 2.getToken client_id client_secret code
* */
mWebView.loadUrl(UrlConfig.LOGIN_URL);
Log.d("webViewURL",mWebView.getUrl());
}
@Override
protected void onDestroy() {
super.onDestroy();
mWebView.removeAllViews();
mWebView.destroy();
if(mSubscription!=null){
mSubscription.unsubscribe();
}
if(mProgressSubscription!=null){
mProgressSubscription.unsubscribe();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
class MyWebViewClient extends WebViewClient{
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
Log.d("MyWebViewClient", url);
if(url.contains("?code=")){
Uri uri=Uri.parse(url);
String code=uri.getQueryParameter("code");
getUser(code);
}
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
mProgressSubscription=Observable.timer(1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
mWebView.mProgressBar.setVisibility(View.GONE);
}
});
}
}
private void initView(){
Toolbar toolbar=(Toolbar) findViewById(R.id.toolbar);
mWebView=(WebViewProgress) findViewById(R.id.web_view);
toolbar.setTitle("授权登录");
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
WebSettings webSettings=mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
mWebView.requestFocusFromTouch();
mWebView.setWebViewClient(new MyWebViewClient());
}
private void getUser(String code){
mSubscription=NetWork.getAuthApi().getAccessToken(UrlConfig.CLIENT_ID,UrlConfig.CLIENT_SECRET,code)
.flatMap(new Func1<AccessToken, Observable<User>>() {
@Override
public Observable<User> call(AccessToken accessToken) {
return NetWork.getUserApi().getUser(accessToken.getAccess_token());
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onCompleted() {
Log.d("OAuthLoginActivity", "completed");
}
@Override
public void onError(Throwable e) {
Log.d("OAuthLoginActivity", "e:" + e);
}
@Override
public void onNext(User user) {
Log.d("OK",user.getLogin());
Toast.makeText(OAuthLoginActivity.this, user.getLogin(), Toast.LENGTH_SHORT).show();
}
});
}
}
迷茫2017-04-17 17:39:45
补充:感谢@DOS提醒,增加LayoutParams布局参数设置。
你可以试试我的方法:
不要在布局文件中声明<WebView>,改成在Activity中创建 如,WebView mWebView = new WebView(this);
在布局文件中用容器类布局,比如FrameLayout作为WebView的容器,在Activity中主动把WebView添加到容器中。
在OnDestory()中移除、销毁WebView。
举个例子吧:我们用FrameLayout作为WebView的父容器
1: 使用容器包裹WebView
<FrameLayout
android:id="@+id/container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
2:在Activity中创建WebView,在OnDestroy()方法中从容器中移除、销毁WebView
public class MyActivity extends Activity {
private FrameLayout mContainer;
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mContainer = (FrameLayout) findViewById(R.id.container);
mWebView = new WebView(this);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
mWebView.setLayoutParams(p);
mContainer.addView(mWebView);
}
@Override
protected void onDestroy() {
super.onDestroy();
mContainer.removeAllViews();
mWebView.destroy();
}
}
之所以这么做的原因是在XML文件中创建WebView,会把Activity作为Context传给WebView,而不是Application Context。所以在finishingActivity的时候,WebView任然持有Activity引用,导致Activity无法被回收。更多详情,戳这里