简体   繁体   English

多次启动/调用同一线程Java Android

[英]Starting/Calling the same thread multiple times Java Android

I need to call the same thread multiple times in my app. 我需要在我的应用中多次调用同一线程。 Using my original code, the first time is can be executed just fine. 使用我的原始代码,第一次执行就可以了。 But the second time it crashes - I then learned that each thread shall only be executed not more than one time. 但是第二次崩溃-然后我了解到每个线程最多只能执行一次。

My original piece of code: 我的原始代码:

View.OnClickListener myClickListener = new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        mythread.start();
    }
};


Thread mythread = new Thread(){

    @Override
    public void run() {

        runOnUiThread(new Runnable() {
            public void run() {
                demoBt.setText("Running...");
            }
        });

     try {
        sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }       

        runOnUiThread(new Runnable() {
            public void run() {
                demoBt.setText("Finished...");
            }
        });
    }
};

So as I said, it crashes if I try to run it for the second time. 因此,正如我所说,如果我尝试第二次运行它,它将崩溃。 So I tried modifying it like: 所以我试着像这样修改它:

View.OnClickListener myClickListener = new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        test();
    }
};

private void test(){

    Thread mythread = new Thread(){

        @Override
        public void run() {

            runOnUiThread(new Runnable() {
                public void run() {
                    demoBt.setText("Running...");
                }
            });

         try {
            sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }       

            runOnUiThread(new Runnable() {
                public void run() {
                    demoBt.setText("Finished...");
                }
            });
        }
    };

    mythread.start();
}

It works very good; 效果很好; but my question is that whether this is the correct way to do this action or there is a more optimal way to do this? 但我的问题是,这是执行此操作的正确方法,还是有更优化的方法?

Also, is it an acceptable thing to call a thread from insider of another thread? 另外,从另一个线程的内部人员调用线程是否可以接受? (like the way I put stuff on UI Thread inside the new thread of mine) (就像我在我的新线程中将内容放到UI线程上的方式一样)

EDIT: This is just an example. 编辑:这只是一个例子。 For my actual code I have heavy math-based simulation to be done which takes 10sec to be done. 对于我的实际代码,我需要进行大量基于数学的模拟,这需要10秒的时间。 Based on the results that will be shown to the user , they may want to change their input parameters and let the simulation run again. 根据将显示给用户的结果,他们可能希望更改其输入参数,然后再次运行仿真。 This will happen several times. 这将发生几次。

In addition to the other good answers about using AsyncTask or runOnUiThread(), you could define a private member as a Runnable, like this: 除了关于使用AsyncTask或runOnUiThread()的其他良好答案之外,您还可以将私有成员定义为Runnable,如下所示:

private Runnable mytask = new Runnable() {
    @Override
    public void run() {

        runOnUiThread(new Runnable() {
            public void run() {
                demoBt.setText("Running...");
            }
        });

     try {
        sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }       

        runOnUiThread(new Runnable() {
            public void run() {
                demoBt.setText("Finished...");
            }
        });
    }
};

Then, whenever you want to run it, do 然后,无论何时要运行它,都要做

new Thread(mytask).start();

There is nothing bad with that but I think a better way would be using AsyncTask . 这样做没有什么不好,但是我认为更好的方法是使用AsyncTask It is exactly designed for this cases. 正是针对这种情况而设计的。

You can use AsyncTask multiple times just creating a new one like this new MyAsyncTask().execute(""); 您可以使用AsyncTask多次,只需创建一个new MyAsyncTask().execute(""); (source from here ) (来自此处

Also, is it an acceptable thing to call a thread from insider of another thread? 另外,从另一个线程的内部人员调用线程是否可以接受? (like the way I put stuff on UI Thread inside the new thread of mine) (就像我在我的新线程中将内容放到UI线程上的方式一样)

runOnUiThread exists solely for that purpose. runOnUiThread专门用于此目的。 But there are usually much better ways (eg AsyncTask ) so using this method is probably a bad idea. 但是通常有更好的方法(例如AsyncTask ),因此使用此方法可能不是一个好主意。

my question is that whether this is the correct way to do this action or there is a more optimal way to do this? 我的问题是,这是执行此操作的正确方法,还是有更优化的方法?

You should not use a thread just to schedule future tasks. 您不应仅使用线程来安排将来的任务。 They are useful to execute something in parallel to the main thread but add lots of potential errors (try rotating the screen between it prints running..finished, could crash) 它们对于与主线程并行执行某些操作很有用,但会增加许多潜在的错误(尝试在运行打印的屏幕之间旋转屏幕。完成,可能会崩溃)

I would use a CountDownTimer in your case. 我会在您的情况下使用CountDownTimer

Or a Handler , examples eg here: Schedule task in android Handler ,示例,例如:here: 在Android中安排任务

From the provided code I assume that you want to perform an UI operation before and after your long mathematical computation. 从提供的代码中,我假设您要在长时间的数学计算之前和之后执行UI操作。 In such as @Andres suggested, AsyncTask is your best buy. 在@Andres建议的情况下,AsyncTask是您的最佳选择。 It provides method onPreExecute, onPostExecute which runs on UI thread, and thus no need for explicitly calling runOnUiThread. 它提供了在UI线程上运行的onPreExecute和onPostExecute方法,因此无需显式调用runOnUiThread。

Key concepts : 关键概念 :

  1. You can't start an already started thread. 您无法启动已经启动的线程。 This will return in an IllegalStateException. 这将返回IllegalStateException。 If you need to perform same task again, you should create a new instance. 如果需要再次执行相同的任务,则应创建一个新实例。

  2. If you find yourself creating several instances of a thread (even AsyncTask), since you need to run same task again and again, I would suggest you to use Thread Pool or simple Java Executor Service. 如果您发现自己创建了一个线程的多个实例(甚至是AsyncTask),则由于需要一次又一次地运行相同的任务,建议您使用线程池或简单的Java Executor Service。 Create a singleThread or may be pool and post your runnable onto executorService and it will take care of the rest. 创建一个singleThread或将其作为池并将您的可运行项发布到executorService,其余的将由它负责。

  3. Inter-Thread or Inter-Process communication is quite common requirement. 线程间或进程间通信是相当普遍的要求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM