2012-06-21 59 views
7

当我的应用程序进行回调时,我有相当多的工作要做(读取&通过ORM库和一些基于距离的计算来写入SQL数据库)。当然,我担心不会阻止主UI线程,所以我一直在尝试(不成功)来确定这是否是进行回调的线程。如果是这样,我打算在进行回调时触发AsyncTask执行上述所有工作。同样的AsyncTask也会接收来自2个独立活动类的事件。 (回应用户输入等)onLocationChanged回调是在什么线程上进行的?主UI线程?

围绕此回调发现的很多讨论似乎基于人们试图更改实际接收回调的线程。这对我来说没有意义。当然平台决定了这个回调的上下文,当接收到这个回调时,明智的做法是将任何严肃的工作转移到另一个线程上,而AsyncTask似乎是合适的。

如果任何人都可以勾画出他们在这里使用过的成功模式,那将会非常有用。

回答

7

根据用于LocationManager Android的参考文档:

调用线程必须是一个弯针线如 呼叫Activity主线程。

这意味着初始化回调的线程必须是主线程或线程的Looper

我发现处理此问题的最佳方法是在主线程上注册一个OnLocationChanged接收器。然后,在我的回调中,我将创建一个Runnable以发送到后台线程,在那里执行任何长时间运行的任务(如写入数据库)。

ExecutorService mThreadPool = Executors.newSingleThreadExecutor(); 

@Override 
public void onLocationChanged(Location location) { 
    mThreadPool.execute(new Runnable() { 
     @Override 
     public void run() { 
      // Perform your long-running tasks here. 
      //... 
     } 
    }); 
} 
+0

从文档看来,重新调用onLocationChanged的线程取决于传递给使用requestLocationUpdate(..)调用的参数。另外,如果Looper不是其中一个参数,那么回调将在主UI线程的上下文中进行。需要阅读更多关于Loopers的信息。上面的解决方案看起来很明智。我现在想知道它在性能方面与使用AsyncTask的比较。所以我会去阅读文档,因为我应该首先完成文档。谢谢您的帮助。 –

+0

你说得对,有几个选项可以用来注册一个LocationListener回调函数。阅读文档是绝对推荐的。上述解决方案大致相当于使用'AsyncTask'。我相信如果你看看AsyncTask类的源代码,你会发现它在内部使用了一个'ExecutorService'。但是,如果您在任务完成时不需要与UI线程交互,则会发现“AsyncTask”的功能超出您的需求。 – twaddington

相关问题