一:工做線程中的回掉更新UI異步
public class MainActivity extends AppCompatActivity { private int i; private Callback mCallback; private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.text); mCallback = new Callback() { @Override public void callback(int i) { textView.setText("i"); } }; doWorkAsNewThread(5000,mCallback); } /** * 開啓工做線程 * @param delayMs 延時,以便對比 * @param callback 回掉,更新Ui */ private void doWorkAsNewThread(final long delayMs, final Callback callback){ new Thread(){ @Override public void run() { super.run(); try { Thread.sleep(delayMs); } catch (InterruptedException e) { e.printStackTrace(); } do { i++; }while(i<100); callback.callback(i); } }.start(); } interface Callback{ void callback(int i); }
能夠看到5s後報錯了:Only the original thread that created a view hierarchy can touch its views.ide
二:改造2,在線程裏切換到UI線程回掉oop
private void doWorkAsNewThread(final long delayMs, final Callback callback){ new Thread(){ @Override public void run() { super.run(); try { Thread.sleep(delayMs); } catch (InterruptedException e) { e.printStackTrace(); } do { i++; }while(i<100); textView.post(new Runnable() { @Override public void run() { callback.callback(i); } }); } }.start(); }
這樣是可行的,沒報錯。直接在Callback中改也能夠:post
mCallback = new Callback() { @Override public void callback(final int i) { textView.post(new Runnable() { @Override public void run() { textView.setText(String.valueOf(i)); } }); } };
可是兩邊都有回掉的話,好像會有問題。spa
三:異步線程內,用handler去更新是無效的。線程
new Handler().post(new Runnable() { @Override public void run() { textView.setText(String.valueOf(i)); } });
Can't create handler inside thread that has not called Looper.prepare()code
加上loop同樣仍是其餘線程。blog
Looper.prepare(); new Handler().post(new Runnable() { @Override public void run() { textView.setText(String.valueOf(i)); } }); Looper.loop();
四:回掉自行區分選擇在哪一個線程:get
private void callbackOnWorkThread(final int i, final Callback callback){ Looper.prepare(); new Handler().post(new Runnable() { @Override public void run() { callback.callback(i); } }); Looper.loop(); } private void callbackOnMainThread(final int i, final Callback callback){ new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { callback.callback(i); } }); }