使用Otto进行内存泄漏的Leakcanary报告
继续我的上一个问题 ,这是我无法摆脱的第二次内存泄漏..
我读到我需要根据Activity和Fragment生命周期注册和取消注册我的静态Otto总线,所以我添加了注册并取消注册到onStop和onStart的调用…有一个触发事件然后由某些片段接收的按钮在Viewpager内部给我以下内存泄漏:
D/LeakCanary﹕ In com.doesnthaveadomain.leo.calendartracker:1.0:1. D/LeakCanary﹕ * com.doesnthaveadomain.leo.calendartracker.MyFragment has leaked: D/LeakCanary﹕ * GC ROOT static com.doesnthaveadomain.leo.calendartracker.MyBus.BUS D/LeakCanary﹕ * references com.squareup.otto.Bus.handlersByType D/LeakCanary﹕ * references java.util.concurrent.ConcurrentHashMap.table D/LeakCanary﹕ * references array java.util.concurrent.ConcurrentHashMap$Node[].[3] D/LeakCanary﹕ * references java.util.concurrent.ConcurrentHashMap$Node.val D/LeakCanary﹕ * references java.util.concurrent.CopyOnWriteArraySet.al D/LeakCanary﹕ * references java.util.concurrent.CopyOnWriteArrayList.elements D/LeakCanary﹕ * references array java.lang.Object[].[0] D/LeakCanary﹕ * references com.squareup.otto.EventHandler.target D/LeakCanary﹕ * leaks com.doesnthaveadomain.leo.calendartracker.MyFragment instance
我的代码..
主要活动
import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import java.lang.ref.WeakReference; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewPager mViewPager = (ViewPager) findViewById(R.id.viewpager); MyAdapter myAdapter = new MyAdapter(getSupportFragmentManager(), this); mViewPager.setAdapter(myAdapter); mViewPager.setCurrentItem(5); Button button = (Button) findViewById(R.id.do_something); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MyBus.getInstance().post(new SomeEvent("Something")); } }); } static class SomeEvent { String mString; SomeEvent(String string) { mString = string; } public String getString() { return mString; } } } class MyAdapter extends FragmentStatePagerAdapter { private int mNumberOfViews; private final WeakReference mActivityWeakRef; public MyAdapter(FragmentManager fm, AppCompatActivity activity) { super(fm); mActivityWeakRef = new WeakReference(activity); mNumberOfViews = 10; } @Override public Fragment getItem(int position) { MyFragment myFragment = new MyFragment(); AppCompatActivity activity = mActivityWeakRef.get(); if (activity != null) { MyApp.getRefWatcher(mActivityWeakRef.get()).watch(myFragment); } return myFragment; } @Override public int getCount() { return mNumberOfViews; } }
MyFragment
import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.squareup.otto.Subscribe; /** * A placeholder fragment containing a simple view. */ public class MyFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_test, container, false); } @Override public void onStart() { super.onStart(); MyBus.getInstance().register(this); } @Override public void onStop() { super.onStop(); MyBus.getInstance().unregister(this); } @Subscribe public void onEvent(MainActivity.SomeEvent event) { } }
布局,以防万一.. MainActivity:
分段:
您正在使用在错误的时间观看参考。 当你绝对确定垃圾收集时,你应该只调用watch(thing)
。 对于您的活动和片段,您将需要以下内容:
@Override public void onDestroy() { super.onDestroy(); RefWatcher refWatcher = ExampleApplication.getRefWatcher(getActivity()); refWatcher.watch(this); }
这是来自LeakCanary FAQ “如何使用它?” 部分
- 是什么导致Android Dalvik java.lang.VerifyError“数组索引的无效的reg类型”?
- 使用DownloadManager类从WebView下载文件
- Youtube API v3搜索video,检索标题和url
- 如何在aglass活动中滚动活卡
- 由于Gradle失败,无法编译任何Android项目:找不到javax.xml.datatype.DatatypeFactory
- 在onViewCreated()中选择复选框的问题
- Android中使用DateFormat的java.lang.IllegalArgumentException
- 从OnClickListener接口创建对象
- Android上的Log4j2