Skip to content
This repository was archived by the owner on Aug 16, 2021. It is now read-only.

Memory Leak_zh

晨鹤 edited this page Dec 19, 2017 · 1 revision

由于未知的原因,所有的监听器 (Listener) 短时间内无法被释放,即使已经被 remove 甚至置 null 也无济于事。根据内存分析,目前初步判断是 Ticwear SDK 内部原因。此问题已经与 Ticwear 公司技术人员沟通,但截至目前尚无结论。如果你在 Activity 中 new 了 Listener ,那么由于 java 内部类对象会持有外部类引用,Activity 便无法被及时回收,遂发生内存泄漏。

目前提供2个解决方案。

继承 WearTools 提供的 Activity

推荐使用此方案。

WearTools 提供了三种 Activity ,分别是 WTActivity WTAppCompatActivity WTFragmentActivity,他们分别继承了 Activity AppCompatActivity FragmentActivity.

这三个类内部实现了可以避免内存泄漏的 Listener,你可以通过 Activity 自身提供的 addMessageListener()addDataListener() 函数启用内置监听器,并且重写 onMessageReceived() onDataChanged() onDataDeleted() 这三个方法来获得回调。默认情况下,会在 onPause() 中注销监听器并在 onResume() 中重新注册(如果已经启用的话)。

下面是一个 Demo 展示如何继承 WTActivity 并启用监听:

public class MainActivity extends WTActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addMessageListener(); //启用msg监听
        addDataListener(); //启用data监听
    }

    @Override
    protected void onMessageReceived(String nodeId, String path, byte[] data, byte[] bothwayId) 	{
		super.onMessageReceived(nodeId, path, data, bothwayId);
		Log.i(TAG, "Receive msg: " + new String(data));
    }

    @Override
    protected void onDataChanged(String path, DataMap dataMap) {
        super.onDataChanged(path, dataMap);
        Log.i(TAG, "Receive data: " + s);
    }

    @Override
    protected void onDataDeleted(String path) {
        super.onDataDeleted(path);
        Log.i(TAG, "Del data: " + path);
    }
}

自定义静态类继承 Listener

不推荐此方案。

其实上述 WearTools 提供的三种 Activity 内部就是使用了此方案,因此,直接继承他们是更加方便快捷的做法。如果满足不了需求,你也可以自己来定义静态类继承 Listener。

此方案与 Handler 引发内存泄漏解决方案一样。大概就是将 Listener 定义为静态类,如此一来便不再持有外部类的引用。为了在回调中操作外部类的变量,可以添加一个外部类的若引用。

下面是一个此方案的 Demo:

public class MainActivity extends Activity {
	private MyMessageListener messageListener;
	private MyDataListener dataListener;
  
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		messageListener = new MyMessageListener(this);
		dataListener = new MyDataListener(this);
	}
  
	@Override
	protected void onResume() {
        super.onResume();
		WTRegister.addMessageListener(this, messageListener);
		WTRegister.addDataListener(this, dataListener);
    }
  
	@Override
	protected void onPause() {
        if (messageListener != null)
            WTRegister.removeMessageListener(this, messageListener);
        if (dataListener != null)
            WTRegister.removeDataListener(this, dataListener);
        super.onPause();
	}

	//定义 WTMessageListener 的静态类
	private static class MyMessageListener extends WTMessageListener {
		private WeakReference<WTActivity> mActivityWeakReference;

		public MyMessageListener(@NonNull WTActivity activity) {
			mActivityWeakReference = new WeakReference<WTActivity>(activity);
		}

		@Override
		public void onMessageReceived(String nodeId, String path, byte[] data, byte[] 		 bothwayId) {
			WTActivity activity = mActivityWeakReference.get();
			if (activity == null) return;
         	// Do something here.
		}
	}

	//定义 WTDataListener 的静态类
	private static class MyDataListener extends WTDataListener {
		private WeakReference<WTActivity> mActivityWeakReference;

		public MyDataListener(@NonNull WTActivity activity) {
			mActivityWeakReference = new WeakReference<>(activity);
		}

		@Override
		public void onDataChanged(String path, DataMap dataMap) {
			WTActivity activity = mActivityWeakReference.get();
			if (activity == null) return;
			// Do something here.
		}

		@Override
		public void onDataDeleted(String path) {
			WTActivity activity = mActivityWeakReference.get();
			if (activity == null) return;
			// Do something here.
		}
	}
}

Clone this wiki locally