android-studio - android webview 内存泄漏
PHP中文网
PHP中文网 2017-04-17 17:37:45
0
3
693

每次启动这个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();
                    }
                });
    }
}
PHP中文网
PHP中文网

认证0级讲师

全員に返信(3)
迷茫

追加: LayoutParams レイアウト パラメーター設定の追加を思い出させてくれた @DOS に感謝します。

私の方法を試すことができます:

  1. レイアウト ファイル内で <WebView> を宣言せず、代わりに、WebView mWebView = new WebView(this);

  2. のように作成します。
  3. WebView のコンテナとして FrameLayout などのコンテナクラスのレイアウトをレイアウトファイルで使用し、Activity で積極的に WebView をコンテナに追加します。

  4. OnDestory() で WebView を削除して破棄します。

例: FrameLayout を WebView の親コンテナとして使用します

1: コンテナを使用して WebView をラップします

リーリー

2: アクティビティで WebView を作成し、OnDestroy() メソッドでコンテナから WebView を削除して破棄します

リーリー

この理由は、XML ファイルで WebView を作成するときに、アクティビティがアプリケーション コンテキストではなくコンテキストとして WebView に渡されるためです。したがって、アクティビティを終了しても、WebView はアクティビティ参照を保持したままになり、アクティビティがリサイクルされなくなります。詳細については、ここをクリックしてください

いいねを押す +0
伊谢尔伦

作成者は MAT を使用して、どのオブジェクトが Activity オブジェクトを保持しているかを分析し、問題を特定できます。

いいねを押す +0
PHPzhong

もう 1 つ追加します: 独立したプロセス

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート