此代码是否在与主UI线程不同的线程中执行

时间:2014-09-11 13:26:36

标签: android multithreading handler

我一直在努力学习android上的线程概念。我认为下面的代码是在主UI线程的不同线程上运行但我不是100%肯定所以我想我会来这里澄清,因为android文档不是用我理解的任何语言编写的。下面是我的代码。

    public void retrieveImages(final ImagePresenterInt imagepresenter) {

       storedImages = new ArrayList<Image>();

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {

                File imagedir = new File("/mnt/shared/images");
                File [] myfiles = File.listRoots();
                String canread = String.valueOf(imagedir.canRead());
                String isfile = String.valueOf(imagedir.isFile());
                String isdir = String.valueOf(imagedir.isDirectory());

                Log.d("Can Read?","Canread from file :" + canread);
                Log.d("is file?","Is a  file ? :" + isfile);
                Log.d("is dir?","Is a Dir file :" + isdir);

               File [] rootfiles =myfiles[0].listFiles();

                for (File item : rootfiles)
                {
                    Log.d(item.getAbsolutePath(),item.getName());
                }

                if(Looper.myLooper() == Looper.getMainLooper())
                {
                    Log.d("main thread ?", "YES");
                }
            }
        }, 2000);


}

我对上面代码的理解是我创建了一个处理程序。它与主线程或UI线程相关联。它有一个消息队列和一个与之关联的looper。这个代码被传递到消息队列并由looper在一个单独的线程上运行到主UI线程?我在这里错了。但主要是我想知道这是否在主线程上运行。如果没有,我怎么会把它带到另一个线程?我尝试使用在此问题中找到的代码验证代码是否在不同的线程上运行

How to check if current thread is not main thread

这显然告诉我Iam仍然在主线程中运行。谢谢你的帮助

2 个答案:

答案 0 :(得分:1)

您在Handler中创建的retrieveImages()绑定到调用此函数的线程。

The doc on Handler说:

  

默认构造函数将此处理程序与当前线程的Looper相关联。如果此线程没有looper,则此处理程序无法接收消息,因此会抛出异常。

因此,如果从UI线程调用retrieveImages(),则在其中创建的Handler也绑定到UI线程。

更新:如果您希望代码在不同的线程中执行,最简单的方法是使用AsyncTask

答案 1 :(得分:0)

Handler是在调用线程中创建的,在你的情况下可能是UI-Thread。如果你想开始一个新线程,我知道有三种可能性:第一种是简单地开始一个新线程:

thread = new Thread() {
  @Override
  public void run() {
  //Do your thing here
  }
};
thread.start();

如果你的Activity被杀,线程就会死掉。

第二个是定义IntentService:

public class SimpleIntentService extends IntentService {

    public SimpleIntentService() {
        super("SimpleIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
    //Do your thing here
    }

并通过

启动它
Intent intent = new Intent(this, SimpleIntentService.class);
intent.putExtra("SomeString", "SomeValueYouNeed");
startService(intent);

IntentService将一直运行,直到onHandleIntent()完成,然后自行关闭。

第三种可能性是AsyncTask:

 private class TestTask extends AsyncTask<Datatype1, Datatype2, Datatype3>{
     protected Long doInBackground(Datatype1... params) {
     // Do your thing here  
     }

     protected void onProgressUpdate(Datatype2... progress) {
         //Do a Progress-Bar or something like that
     }

     protected void onPostExecute(Datatype3 result) {
         //Do something, when your work is done
     }
 }

在你的活动中:

new TestTask().execute(params);

文档说明你不应该使用Async-Tasks进行很长时间的计算,但我不知道为什么会这样做。如果您使用Asynctask而不是Intentservice,可能更容易将数据恢复到UI-Thread,但我自己也不经常使用它们,所以我可能不是最好的人问这里

编辑:我忘了这个: 对于您传递的每个ntent,IntentService都会执行一次,Asynctask只能调用一次。

此外,必须在Manifest中声明IntentService。