每次启动这个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();
}
});
}
}
추가됨: LayoutParams 레이아웃 매개변수 설정을 추가하도록 상기시켜 준 @DOS에게 감사드립니다.
제 방법을 시도해 보세요:
레이아웃 파일에서 <WebView>를 선언하지 말고 대신 Activity에서 생성하세요. 예를 들어 WebView mWebView(this);
FrameLayout 등 레이아웃 파일의 컨테이너 클래스 레이아웃을 WebView의 컨테이너로 사용하고, Activity의 컨테이너에 WebView를 적극적으로 추가합니다.
OnDestory()에서 WebView를 제거하고 파기합니다.
예: FrameLayout을 WebView의 상위 컨테이너로 사용합니다.
1: 컨테이너를 사용하여 WebView 래핑
으아악2: Activity에서 WebView를 생성하고 OnDestroy() 메서드의 컨테이너에서 WebView를 제거 및 삭제합니다
으아악그 이유는 XML 파일에서 WebView를 생성할 때 액티비티가 애플리케이션 컨텍스트 대신 컨텍스트로 WebView에 전달되기 때문입니다. 따라서 활동을 완료해도 WebView는 여전히 활동 참조를 보유하므로 활동이 재활용되지 않습니다. 자세한 내용은 여기를 클릭하세요
저자는 MAT를 사용하여 어떤 개체가 Activity 개체를 보유하고 있는지 분석한 다음 문제를 찾을 수 있습니다.
또 하나 추가: 독립 프로세스