我是Android新手,我正在尝试使用UI-Thread,所以我写了一个简单的测试活动。但我认为我误解了一些东西,因为点击按钮 - 应用程序不再响应
public class TestActivity extends Activity {
Button btn;
int i = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runThread();
}
});
}
private void runThread(){
runOnUiThread (new Thread(new Runnable() {
public void run() {
while(i++ < 1000){
btn.setText("#"+i);
try {
Thread.sleep(300);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}));
}
}
下面是runThread
函数的修正片段。
private void runThread() {
new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
btn.setText("#" + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gifImageView = (GifImageView) findViewById(R.id.GifImageView);
gifImageView.setGifImageResource(R.drawable.success1);
new Thread(new Runnable() {
@Override
public void run() {
try {
//dummy delay for 2 second
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//update ui on UI thread
runOnUiThread(new Runnable() {
@Override
public void run() {
gifImageView.setGifImageResource(R.drawable.success);
}
});
}
}).start();
}
只需将其作为函数包装,然后从后台线程调用此函数。
public void debugMsg(String msg) {
final String str = msg;
runOnUiThread(new Runnable() {
@Override
public void run() {
mInfo.setText(str);
}
});
}
你有它从前到后。单击按钮会调用runOnUiThread()
,但这不需要,因为单击处理程序已在UI线程上运行。然后,您在runOnUiThread()
中的代码将启动一个新的后台线程,您尝试执行UI操作,然后失败。
相反,只需直接从您的点击处理程序启动后台线程。然后,在对btn.setText()
的调用中包含对runOnUiThread()
的调用。
runOnUiThread(new Runnable() {
public void run() {
//Do something on UiThread
}
});
有几种使用runOnUiThread()的技术,让我们看看所有
这是我的主线程(UI线程),名为AndroidBasicThreadActivity,我将以各种方式从工作线程更新它 -
public class AndroidBasicThreadActivity extends AppCompatActivity
{
public static TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_android_basic_thread);
textView = (TextView) findViewById(R.id.textview);
MyAndroidThread myTask = new MyAndroidThread(AndroidBasicThreadActivity.this);
Thread t1 = new Thread(myTask, "Bajrang");
t1.start();
}
}
1.)通过将Activity的实例作为工作线程的参数传递
class MyAndroidThread implements Runnable
{
Activity activity;
public MyAndroidThread(Activity activity)
{
this.activity = activity;
}
@Override
public void run()
{
//perform heavy task here and finally update the UI with result this way -
activity.runOnUiThread(new Runnable()
{
@Override
public void run()
{
AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
}
});
}
}
2.)在工作线程中使用View的post(Runnable runnable)方法
class MyAndroidThread implements Runnable
{
Activity activity;
public MyAndroidThread(Activity activity)
{
this.activity = activity;
}
@Override
public void run()
{
//perform heavy task here and finally update the UI with result this way -
AndroidBasicThreadActivity.textView.post(new Runnable()
{
@Override
public void run()
{
AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
}
});
}
}
3.)通过使用android.os包中的Handler类如果我们没有上下文(this / getApplicationContext())或Activity的实例(AndroidBasicThreadActivity.this)那么我们必须使用如下的Handler类 -
class MyAndroidThread implements Runnable
{
Activity activity;
public MyAndroidThread(Activity activity)
{
this.activity = activity;
}
@Override
public void run()
{
//perform heavy task here and finally update the UI with result this way -
new Handler(Looper.getMainLooper()).post(new Runnable() {
public void run() {
AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
}
});
}
}
如果在片段中使用,则只需编写
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
//Do something on UiThread
}
});
你的这个:
@UiThread
public void logMsg(final String msg) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Log.d("UI thread", "I am the UI thread");
}
});
}
您可以使用此示例:
在以下示例中,我们将使用此工具来发布由后台线程处理的同义词搜索的结果。
为了在OnCreate活动回调期间完成目标,我们将设置onClickListener以在创建的线程上运行searchTask。
当用户单击“搜索”按钮时,我们将创建一个Runnable匿名类,用于搜索在R.id.wordEt EditText中键入的单词并启动该线程以执行Runnable。
搜索完成后,我们将创建一个Runnable SetSynonymResult实例,以通过UI线程将结果发布回同义词TextView。
这种技术有时不是最方便的技术,特别是当我们无法访问Activity实例时;因此,在接下来的章节中,我们将讨论更简单和更清晰的技术,以便从后台计算任务更新UI。
public class MainActivity extends AppCompatActivity {
class SetSynonymResult implements Runnable {
String synonym;
SetSynonymResult(String synonym) {
this.synonym = synonym;
}
public void run() {
Log.d("AsyncAndroid", String.format("Sending synonym result %s on %d",
synonym, Thread.currentThread().getId()) + " !");
TextView tv = (TextView) findViewById(R.id.synonymTv);
tv.setText(this.synonym);
}
}
;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button search = (Button) findViewById(R.id.searchBut);
final EditText word = (EditText) findViewById(R.id.wordEt);
search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Runnable searchTask = new Runnable() {
@Override
public void run() {
String result = searchSynomim(word.getText().toString());
Log.d("AsyncAndroid", String.format("Searching for synonym for %s on %s",
word.getText(), Thread.currentThread().getName()));
runOnUiThread(new SetSynonymResult(result));
}
};
Thread thread = new Thread(searchTask);
thread.start();
}
});
}
static int i = 0;
String searchSynomim(String word) {
return ++i % 2 == 0 ? "fake" : "mock";
}
}
资源 :
这就是我使用它的方式:
runOnUiThread(new Runnable() {
@Override
public void run() {
//Do something on UiThread
}
});