从另一个类线程更新的Android UI(Update Android UI from a thre

2019-08-17 02:24发布

我已经看到了在这里问类似的问题了几个问题,但我还没有看到合适的答案。 很多人都问如何更新从一个线程的用户界面,但他们几乎总是在同一类的UI。

我正在试图做的是从更新已在另一个类中创建线程的UI。 我见过所有的建议,如异步,处理程序,可运行,等等...但我已经有单独的类实现它们真正的麻烦。

我试图让我的UI类极小,只处理与GUI交互,当用户按下一个按钮,例如。 现在,我已经创建了一个新的线程,在一个新的类,它连接到蓝牙设备,但后来我想从一个“连接”按钮,将“断开”按钮更改UI线程按钮(即变化从创建蓝牙套接字关闭它)按钮。

什么是做到这一点的一般方法是什么? 我在想这都是错误的,应该有一个班的一切吗? 什么是“主” UI类和其他类/线程之间进行交互的正确方法?

理想的情况是我希望能够做其他的UI交互,所以一些解决方案,它允许UI类以外的其他用户界面的变化将是巨大的!

Answer 1:

我正在试图做的是从更新已在另一个类中创建线程的UI。 我见过所有的建议,如异步,处理程序,可运行,等等...但我已经有单独的类实现它们真正的麻烦。

一般对于你的目标,我建议你使用:

  • AsyncTask
  • IntentServiceResultReceiver

我不认为它太棘手。 绝对不。 如果你拥有了它在一些分隔的类(ES)而不是内部类(ES) Activity类,所以我建议使用构造函数,你将通过背景,窗口小部件,通常任何你想要的,然后在正确的方法(它允许用户界面更新)更新UI

我这样做,因为当我有干净的班我喜欢(这样的UI类只有UI实现和逻辑单独放置)。

例:

public class TaskExample extends AsyncTask<Void, Integer, Void> {

   private Context c;
   private Button b;

   public TaskExample(Context c, Button b) {
      this.c = c;
      this.b = b;
   }

   protected Void doInBackground(Void... params) {
      // some work
      if (isSomethingConnected) {
         publishProgress(Constants.IS_CONNECTED);
      }
      return null;
   }

   public void onProgressUpdate(Integer... params) {
       switch (params[0]) {
          case Constants.IS_CONNECTED:
             b.setText("Connected");
          break;
          case Constants.ANOTHER_CONSTANT:
             // another work
          break;
       }
   }  
}

用法:

public class Main extends Activity implements View.OnClickListener {

   private Button b;

   public void onCreate(Bundle b) {
      super.onCreate(b);
      // initialise widgets and set listeners to appropriate widgets
   }

   public void onClick(View v) {
      switch(v.getId()) {
         case R.id.connectBtn:
            startWorker();
         break;
      }
   }

   private void startWorker() {
      TaskExample te = new TaskExample(this, b);
      te.execute();
   }
}


Answer 2:

有一对夫妇的选择。 如果你有机会到要更改的查看和只需要强制刷新,您可以使用View.postInvalidate()从任何线程。 如果您需要更复杂的操作,例如更改按钮上的文字,你应该使用runOnUIThread ,这需要访问Activity上下文。 这应该是简单的让 - 只需添加它作为您的自定义对象的构造函数的参数。 有了这个背景,你可以这样做:

activityContext.runOnUiThread(new Runnable(){
    @Override
    public void run() {
        myButton.setText("disconnect");
    }
});


Answer 3:

使用runOnUiThread(Runnable)方法来运行主线程上的东西,并调用ClassName.View.invalidate()方法,如果它是一个视图或只是做一个public的方法在你的目标类,处理用户界面的清爽。



文章来源: Update Android UI from a thread in another class