另一个线程的代码怎么能在主线程上运行?

时间:2016-03-06 16:31:29

标签: java android multithreading heap-memory android-handler

最近,我对一些Android API感到困惑。这里有一些简化的解释,因为代码有点长,这是完全正确的,但只是让我迷惑。

我有两个主题:UI线程和另一个名为HandlerThread的{​​{1}}。

AThread是在UI线程中创建的mResponseHander,它显然与UI线程的looper相关联。然后我将Handler传递给mResponseHandler

AThreadAThread,可以执行一些图像下载任务。在HandlerThread中,我写了一些代码:

AThread

此外,变量mResponseHandler.post(new Runnable() { @Override public void run() { if (mRequestMap.get(target) != url) { return; } mRequestMap.remove(target); mThumbnailDownloadListener.onThumbnailDownloaded(target, bitmap); } }); mRequestMap及其他变量仅在mThumbnailDownloadListener中定义。

我知道当我调用AThread时,mResponseHandler.post(new Runnable)稍后将在UI线程上运行,因为Runnable被关联到UI线程的looper。

以下是一个问题:当UI线程中未定义变量mResponseHandlermRequestMap以及其他变量时,为什么上面的代码在UI线程中运行仍然正确,但仅在{{ 1}}?

1 个答案:

答案 0 :(得分:2)

  

为什么当UI线程中没有定义变量“mRequestMap”和“mThumbnailDownloadListener”以及其他未在AThread中定义时,UI线程中运行的代码仍然正确?

任何类实例(让我们进一步使用“object”)都驻留在JVM heap中(不是“在线程中”或其他任何东西)。将new运算符应用为

Type variableName = new Type();

在堆上分配一块内存,对内存的引用存储为variableName的值。从现在开始,任何对象(例如Thread对象或实现Runnable的对象,就像您的情况一样)具有{{1}的引用(variableName或其副本)对象,可以“操作”它。

话虽如此,通过将Type发布到与UI线程的Runnable关联的处理程序,您告诉线程应该对驻留在堆中的对象执行什么作业,并且可以由LoopermRequestMap推荐。

供参考:Java Memory Model