【问题标题】:Waiting for UI Thread to finish operation in Android等待 UI 线程在 Android 中完成操作
【发布时间】:2021-10-01 08:51:30
【问题描述】:

我在我的onCreate() 方法中处于这种情况:

@Override
protected void onCreate (Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game);

    new Thread(() -> {

        Object obj;

        while (true) {

            // update obj

            runOnUiThread(() -> {
                // display obj
            });

        }

    }).start();

}

这里的问题是更新操作与显示操作不同步:我总是跳过一个值,因为obj 在 UI 线程能够显示其旧值之前更新。

等待 UI 线程完成其显示 obj 的工作然后才进行下一次迭代的正确方法是什么?

【问题讨论】:

  • 我认为您实际上并没有很好地解释您的问题,但通常您不会以这种方式与 UI 线程同步。两个线程都异步地做他们的事情,这很重要。如果你真的认为你需要同步,我认为你需要更好地解释你实际上想要做什么。我认为这里有一个 XY 问题/
  • 链接到 XY 问题:en.wikipedia.org/wiki/XY_problem
  • 最后我通过在 UI 线程上运行这两个操作来解决它
  • 这几乎肯定是错误的解决方案。相反,您通常应该使用在工作线程完成时执行的 callback
  • @outsidethecave 在 UI 线程上运行这两个操作可能会冻结并导致应用程序崩溃,如果这些操作花费了太长时间才能完成。

标签: java android multithreading synchronization ui-thread


【解决方案1】:

您可以在此处使用回调

喜欢,

//Extending the Activity is left here since it isn't the subject
public class MyClass implements MyThread.CallbackListener{
    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);
      
        new MyThread(this).start(); 

        //Your codes that do not require synchronization with the above thread
    }
 
    @Override
    public void onObjectUpdated(Object obj){
        //Your code that needs to be synchronized. In your case display your object here
    }
}

你的 MyThread 类将是

public class MyThread extends Thread{
    Object obj;
    CallbackListener listener; 
   
    public MyThread(CallbackListener listener){
        this.listener = listener;
    }  
    
    public void run(){
       while (true) {
          // update obj
          listener.onObjectUpdated(obj);
       }
    }

    public interface CallbackListener{
       void onObjectUpdated(Object obj);
    } 
}

我们在这里所做的只是在对象更新时进行方法调用。

当对象更新时,您的 MyClass 中的 onObjectUpdated 方法将被调用,从而使您的代码同步。并且您可以将任何非同步代码放在 onCreate 方法本身中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    相关资源
    最近更新 更多