每次启动这个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
Added: Thanks to @DOS for reminding me to add LayoutParams layout parameter settings.
You can try my method:
Don’t declare <WebView> in the layout file, instead create it in Activity. For example, WebView mWebView = new WebView(this);
Use container class layout in the layout file, such as FrameLayout as the container of WebView, and actively add WebView to the container in Activity.
Remove and destroy WebView in OnDestory().
For example: we use FrameLayout as the parent container of WebView
1: Use a container to wrap WebView
<FrameLayout
android:id="@+id/container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
2: Create WebView in Activity, remove and destroy WebView from the container in OnDestroy() method
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();
}
}
The reason for this is that when creating a WebView in an XML file, the Activity will be passed to the WebView as the Context instead of the Application Context. Therefore, when finishing Activity, WebView still holds the Activity reference, causing the Activity to not be recycled. For more details, click here
伊谢尔伦2017-04-17 17:39:45
The poster can use MAT to analyze which object is holding the Activity object, and then the problem can be located.