如何正确使用Workerthread?

时间:2015-03-27 16:12:38

标签: android multithreading android-handler

我几个月来一直在编写Android应用程序,而且我正在构建一个真正需要的应用程序。

由于我希望它能够快速而快速地工作,我让Workerthread在后台执行各种任务,而UI可以......构建,工作和填充。

它基于Android Studio Drawer应用蓝图。

在Main.onCreate中,我得到了operator=new Operator(),其中Thread延伸。

现在,当加载一个新片段时,它有时会调用MainActivity.operator.someMethod()(我让操作符静态,所以我可以从任何地方使用它),经过一段时间我意识到,实际上在后台运行的唯一任务是运算符run()方法和Asynctask我的登录片段运行。 UI等待完成的所有其他内容因此被UI线程执行。

所以我想:没问题!我的operator获得了handler内置run(),我更改了这些任务:

public void run() {
    Looper.prepare();   //Android crashed and said I had to call this
    OpHandler = new Handler();
    LoadLoginData();
    [...Load up some Arrays with hardcoded stuff and compute for later use...]
}

public void LoadLoginData() {
    OpHandler.post(LoadLoginDataRunnable);
}
private Runnable LoadLoginDataRunnable = new Runnable() {
    @Override
    public void run() {
        if(sharedPreferences==null)
            sharedPreferences= PreferenceManager.getDefaultSharedPreferences(context);
        sessionID=sharedPreferences.getString("sessionID", null);
        if(sessionID!=null) {
            postenID = sharedPreferences.getString("postenID", PID_STANDARD);
            postenName = sharedPreferences.getString("postenName", PID_STANDARD);
            context.QuickToast(sessionID, postenName, postenID);
        }
    }
};

context是我的MainActivity,我给操作员一个引用,所以我可以发送Toasts进行调试。

但是现在,Runnables似乎没有运行或完成,任何Log.e或Log.d内容都没有到达控制台。

经过一些googeling和stackoverflowing之后,每个人都只是在解释处理程序,Asynctask和Threads之间的区别。多任务示例始终只显示new Thread(new Runnable{run(task1)}).start次3,具有不同的任务。

因此成了我的大问题:

如何正确地,在较长时间内(MainActivity的生命周期),使用不同的任务,使用后台线程?

编辑:澄清一下,我也想直接解决我的特殊问题。

编辑2:阅读nikis评论后(谢谢),简单的答案似乎是“使用HandlerThread而不是线程”。我回家后会尽快尝试。

立即尝试使用HandlerThread。看来我的OpHandler,在run()中被初始化,在run()完成之后就被破坏了,不知道这里有什么(这是另一个我希望在这里得到解答的谜)。我在run()完成后尝试使用它时会收到NullpointerException。

1 个答案:

答案 0 :(得分:-2)

让您的工作线程拥有一个任务队列。在run()方法中,只需从队列中弹出一个任务并执行它。如果队列为空,请等待它填满。

class Operator extends Thread
{
     private Deque<Runnable> tasks;
     private boolean hasToStop=false;

     void run()
     {
          boolean stop=false;
          while(!stop)
          {
               sychronized(this)
               {
                    stop=hasToStop;
               }
               Runnable task=null;
               synchronized(tasks)
               {
                    if(!tasks.isEmpty())
                         task=tasks.poll();
               }
               if(task!=null)
                   task.run();
          }
     }

     void addTask(Runnable task)
     {
          synchronized(tasks)
          {
               tasks.add(task);
          }
     }

     public synchronized void stop()
     {
          hasToStop=true;
     }
}