android中Handler、Thread、Runnable更新UI的思考

來源:互聯網
上載者:User

在寫一個小應用的時候,我接觸到了一個關於Handler和Thread以及runnable的問題,問了群裡各種人都解決不了,然後查閱大量資料,終於有些瞭解,現在發上來和大家分享。

主要是關於,Thread和Runnable的區別,以及他們在使用Handler時造成的影響~,我先上代碼

下面這個是錯誤的代碼~下面的代碼只要執行到handler中更新UI的部分就會報null 指標錯誤~線程處用的Thread

public class MainActivity extends Activity {TextView text1, text2;Button button;myThread th;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text1 = (TextView)findViewById(R.id.text1);text2 = (TextView)findViewById(R.id.text2);button = (Button)findViewById(R.id.button1);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubth = new myThread();th.start();}});}Handler myHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubswitch (msg.what) {case 1:System.out.println("-----------1--------------");System.out.println(msg.getData().getString("s1"));System.out.println(msg.getData().getString("s2"));try{ text1.setText(msg.getData().getString("s1")); text2.setText(msg.getData().getString("s1"));}catch(Exception e){e.printStackTrace();}break;default:break;}super.handleMessage(msg);}};}class myThread extends Thread{String s1, s2;MainActivity ma = new MainActivity();public void run(){  s1 = "fsdfsgfdsgdfgfdgdhshshs";  s2 = "fsfsdgdshdhdshrehreherh";    Message msg = new Message();  msg.what = 1;  Bundle bundle = new Bundle();  bundle.putString("s1", s1);  bundle.putString("s2", s2);  msg.setData(bundle);  ma.myHandler.sendMessage(msg);}}

上面這段代碼,沒給注釋,但是很簡單,相信大家都能看懂~,這段代碼是錯誤的。

下面給大家上正確的代碼~線程處用的Runnable

public class MainActivity extends Activity {TextView text1, text2;Button button;Thread th;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text1 = (TextView)findViewById(R.id.text1);text2 = (TextView)findViewById(R.id.text2);button = (Button)findViewById(R.id.button1);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubth = new Thread(runnable);th.start();}});}Handler myHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubswitch (msg.what) {case 1:System.out.println("-----------1--------------");System.out.println(msg.getData().getString("s1"));System.out.println(msg.getData().getString("s2"));try{ text1.setText(msg.getData().getString("s1")); text2.setText(msg.getData().getString("s1"));}catch(Exception e){e.printStackTrace();}break;default:break;}super.handleMessage(msg);}};Runnable runnable = new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stub      String s1 = "fsdfsgfdsgdfgfdgdhshshs";  String s2 = "fsfsdgdshdhdshrehreherh";  Message msg = new Message();  msg.what = 1;  Bundle bundle = new Bundle();  bundle.putString("s1", s1);  bundle.putString("s2", s2);  msg.setData(bundle);  MainActivity.this.myHandler.sendMessage(msg);}};}

這是正確的代碼,能正確更新UI。


找到問題以後,我又做了幾個小實驗,發現,其實用Thread也是可以的,也是可以更新UI的,就像這樣

public class MainActivity extends Activity {TextView text1, text2;Button button;myThread th;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text1 = (TextView)findViewById(R.id.text1);text2 = (TextView)findViewById(R.id.text2);button = (Button)findViewById(R.id.button1);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubth = new myThread();th.start();}});}Handler myHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubswitch (msg.what) {case 1:System.out.println("-----------1--------------");System.out.println(msg.getData().getString("s1"));System.out.println(msg.getData().getString("s2"));try{ text1.setText(msg.getData().getString("s1")); text2.setText(msg.getData().getString("s1"));}catch(Exception e){e.printStackTrace();}break;default:break;}super.handleMessage(msg);}};class myThread extends Thread{public void run() {// TODO Auto-generated method stub      String s1 = "fsdfsgfdsgdfgfdgdhshshs";  String s2 = "fsfsdgdshdhdshrehreherh";  Message msg = new Message();  msg.what = 1;  Bundle bundle = new Bundle();  bundle.putString("s1", s1);  bundle.putString("s2", s2);  msg.setData(bundle);  MainActivity.this.myHandler.sendMessage(msg);}}}


到這,不知道大家發現問題在哪沒有?

據我所瞭解~Thread和Runnable的區別如下:

如果然一個線程實現Runnable介面,當調用這個線程對象開闢多線程時,可以讓這些線程調用同一變數~,(說白了就是,我主線程和拋出的子線程都可以用你主線程的變數了)

若這個線程類是繼承自Thread類而來,則通過內部類實現上述功能,利用的就是內部類可任意訪問外部類這一特性(這段說的就是我3段代碼的最後1段)。

好了,完了,就這麼多,希望對大家有協助




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.