我已经看到了在这里问类似的问题了几个问题,但我还没有看到合适的答案。 很多人都问如何更新从一个线程的用户界面,但他们几乎总是在同一类的UI。
我正在试图做的是从更新已在另一个类中创建线程的UI。 我见过所有的建议,如异步,处理程序,可运行,等等...但我已经有单独的类实现它们真正的麻烦。
我试图让我的UI类极小,只处理与GUI交互,当用户按下一个按钮,例如。 现在,我已经创建了一个新的线程,在一个新的类,它连接到蓝牙设备,但后来我想从一个“连接”按钮,将“断开”按钮更改UI线程按钮(即变化从创建蓝牙套接字关闭它)按钮。
什么是做到这一点的一般方法是什么? 我在想这都是错误的,应该有一个班的一切吗? 什么是“主” UI类和其他类/线程之间进行交互的正确方法?
理想的情况是我希望能够做其他的UI交互,所以一些解决方案,它允许UI类以外的其他用户界面的变化将是巨大的!
我正在试图做的是从更新已在另一个类中创建线程的UI。 我见过所有的建议,如异步,处理程序,可运行,等等...但我已经有单独的类实现它们真正的麻烦。
一般对于你的目标,我建议你使用:
-
AsyncTask
-
IntentService
与ResultReceiver
我不认为它太棘手。 绝对不。 如果你拥有了它在一些分隔的类(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();
}
}
有一对夫妇的选择。 如果你有机会到要更改的查看和只需要强制刷新,您可以使用View.postInvalidate()
从任何线程。 如果您需要更复杂的操作,例如更改按钮上的文字,你应该使用runOnUIThread
,这需要访问Activity
上下文。 这应该是简单的让 - 只需添加它作为您的自定义对象的构造函数的参数。 有了这个背景,你可以这样做:
activityContext.runOnUiThread(new Runnable(){
@Override
public void run() {
myButton.setText("disconnect");
}
});
使用runOnUiThread(Runnable)
方法来运行主线程上的东西,并调用ClassName.View.invalidate()
方法,如果它是一个视图或只是做一个public
的方法在你的目标类,处理用户界面的清爽。