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

每次启动这个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>를 선언하지 말고 대신 Activity에서 생성하세요. 예를 들어 WebView mWebView(this);

  2. FrameLayout 등 레이아웃 파일의 컨테이너 클래스 레이아웃을 WebView의 컨테이너로 사용하고, Activity의 컨테이너에 WebView를 적극적으로 추가합니다.

  3. OnDestory()에서 WebView를 제거하고 파기합니다.

예: FrameLayout을 WebView의 상위 컨테이너로 사용합니다.

1: 컨테이너를 사용하여 WebView 래핑

으아악

2: Activity에서 WebView를 생성하고 OnDestroy() 메서드의 컨테이너에서 WebView를 제거 및 삭제합니다

으아악

그 이유는 XML 파일에서 WebView를 생성할 때 액티비티가 애플리케이션 컨텍스트 대신 컨텍스트로 WebView에 전달되기 때문입니다. 따라서 활동을 완료해도 WebView는 여전히 활동 참조를 보유하므로 활동이 재활용되지 않습니다. 자세한 내용은 여기를 클릭하세요

伊谢尔伦

저자는 MAT를 사용하여 어떤 개체가 Activity 개체를 보유하고 있는지 분석한 다음 문제를 찾을 수 있습니다.

PHPzhong

또 하나 추가: 독립 프로세스

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿