我们经常会在后台线程中去做一些耗时的操作,比如去网络取数据。但是当数据取回来,需要显示到页面上的时候,会遇到一些小麻烦,因为我们都知道,android的UI页面是不允许在其他线程直接操作的。下面总结4中方法用来在线程中操作UI界面。
模拟耗时操作
private void connectNet() throws InterruptedException {
Thread.sleep(2000);
}
方法一:Handler
子线程中通过Handler的sendMessage(msg)发送事件:
private void method1() {
new Thread(new Runnable() {
@Override
public void run() {
try {
//耗时操作
connectNet();
//向Handler发送消息
mHadndler.sendEmptyMessage(111);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
方法二:View.post(Runnable)
private void method2() {
myText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
try {
//耗时操作
connectNet();
myText.post(new Runnable() {
@Override
public void run() {
myText.setText("联网结束,更新UI数据");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
});
}
方法三:Activity.runOnUiThread
与view.post类似
private void method3() {
new Thread(new Runnable() {
@Override
public void run() {
try {
//耗时操作
connectNet();
runOnUiThread(new Runnable() {
@Override
public void run() {
myText.setText("runOnUiThread...");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
方法四:AsyncTask
private void method4() {
//UI线程中执行
new LoadTask().execute("www.91dota.com");
}
private class LoadTask extends AsyncTask {
protected void onPostExecute(String result) {
myText.setText(result); //得到来自网络的信息刷新页面
}
protected String doInBackground(Object[] objects) {
return "......";//后台耗时操作
}
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
示例:
附上代码和布局
MainActivity.java
public class MainActivity extends AppCompatActivity {
private TextView myText;
private Handler mHadndler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
myText.setText("收到消息啦..." + msg.what);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myText = findViewById(R.id.myTextView);
}
/**
* 方法一:Handler
*/
private void method1() {
new Thread(new Runnable() {
@Override
public void run() {
try {
//耗时操作
connectNet();
//向Handler发送消息
mHadndler.sendEmptyMessage(111);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
/**
* 方法二:通过View.post(Runnable)
*/
private void method2() {
myText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
try {
//耗时操作
connectNet();
myText.post(new Runnable() {
@Override
public void run() {
myText.setText("联网结束,更新UI数据");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
});
}
/**
* 方法三:Activity.runOnUiThread(Runnable )
*/
private void method3() {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
//耗时操作
connectNet();
myText.setText("runOnUiThread...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
/**
* 方法四:AsyncTask
*/
private void method4() {
//UI线程中执行
new LoadTask().execute("www.91dota.com");
}
private class LoadTask extends AsyncTask {
protected void onPostExecute(String result) {
myText.setText(result); //得到来自网络的信息刷新页面
}
protected String doInBackground(Object[] objects) {
return "......";//后台耗时操作
}
}
private void connectNet() throws InterruptedException {
Thread.sleep(2000);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/myTextView"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="10dp"
android:background="#dea"
android:gravity="center"
android:text="Hello World!" />
</LinearLayout>