Android系统是不允许在非主线程中更新UI的,如果你这样做了,那么你一定遇到过这样的错误提示“android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.”
这个时候就需要使用到Handler了。
我们需要在Activity或者Fragment中新建一个handler. Handler mHandler = new Handler(); 这样也就绑定到了主UI线程中去了。接着你可以使用hander.post(runnable)来更新UI了。主要使用方法如下
1、在主线程中new 一个对象Handler handler = newHandler()(会自动绑定到主线程)。在需要更新的地方使用handler.post(runnable);发送一个runnable对象在runnable的run方法中执行我们想要的操作。代码如下public class TestActivity extends AppCompatActivity {
private Handler mHandler = new Handler(); private ImageView mImageView; @Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
mImageView = (ImageView) findViewById(R.id.image); new Thread(new Runnable() { @Override
public void run() { try {
Thread.sleep(2000);
mHandler.post(new Runnable() { @Override
public void run() {
mImageView.setImageResource(R.mipmap.ic_launcher);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
2、在主线程new 一个handler 在需要更新的地方使用 handler.sendMessage()方法传递一个Message对象。可以使用message对象的arg1参数或者obj参数或者what参数携带参数。在handler中的回调handler.handleMessage方法中执行想做的方法。public class TestActivity extends AppCompatActivity {
private ImageView mImageView; private Handler mHandler = new Handler() { @Override
public void handleMessage(Message msg) { if(msg.what == 0x123) {
mImageView.setImageResource(R.mipmap.ic_launcher);
} super.handleMessage(msg);
}
}; @Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
mImageView = (ImageView) findViewById(R.id.image); new Thread(new Runnable() { @Override
public void run() { try {
Thread.sleep(2000);
mHandler.sendEmptyMessage(0x123);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
3、在主线程新建一个Runnable对象和Handler对象。在需要子线程中使用handler.post()来更新操作。public class TestActivity extends AppCompatActivity {
private ImageView mImageView; private Handler mHandler = new Handler() ; private Runnable mRunnable = new Runnable() { @Override
public void run() { try {
Thread.sleep(1000);
mImageView.setImageResource(R.mipmap.ic_launcher);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}; @Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
mImageView = (ImageView) findViewById(R.id.image); new Thread(new Runnable() { @Override
public void run() { try {
Thread.sleep(2000);
mHandler.post(mRunnable);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
上面的代码会存在一个问题,当这个runnable被post出去后会进入无线循环,一直发送runnable。如何解决这个问题呢,各位看官瞧这里。mHandler.removeCallbacks(mRunnable);11
你的支持是我写博客的动力