我們經常會在后台線程中去做一些耗時的操作,比如去網絡取數據。但是當數據取回來,需要顯示到頁面上的時候,會遇到一些小麻煩,因為我們都知道,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>
參考:http://www.it165.net