在一个android服务,我已经创建线程(s)做一些后台任务。
我有一个线程需要在主线程的消息队列上发布某个任务的情况,例如一个可运行的。
有没有办法得到主线程的处理程序和post Message/Runnable到它从我的其他线程?
在一个android服务,我已经创建线程(s)做一些后台任务。
我有一个线程需要在主线程的消息队列上发布某个任务的情况,例如一个可运行的。
有没有办法得到主线程的处理程序和post Message/Runnable到它从我的其他线程?
当前回答
HandlerThread是更好的选择,以正常的java线程在Android。
创建一个HandlerThread并启动它 从HandlerThread:requestHandler中创建一个Looper Handler 在requestHandler上发布一个可运行任务
从HandlerThread与UI线程通信
为主线程创建一个Looper Handler: responseHandler并重写handleMessage方法 在其他线程(在本例中为HandlerThread)的可运行任务中,调用responseHandler上的sendMessage responseHandler中handleMessage的sendMessage结果调用。 从Message中获取属性并处理它,更新UI
示例:用从web服务接收到的数据更新TextView。由于web服务应该在非ui线程上调用,因此为网络操作创建了HandlerThread。一旦你从web服务获得内容,发送消息到你的主线程(UI线程)处理程序,该处理程序将处理消息并更新UI。
示例代码:
HandlerThread handlerThread = new HandlerThread("NetworkOperation");
handlerThread.start();
Handler requestHandler = new Handler(handlerThread.getLooper());
final Handler responseHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
txtView.setText((String) msg.obj);
}
};
Runnable myRunnable = new Runnable() {
@Override
public void run() {
try {
Log.d("Runnable", "Before IO call");
URL page = new URL("http://www.your_web_site.com/fetchData.jsp");
StringBuffer text = new StringBuffer();
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
conn.connect();
InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
BufferedReader buff = new BufferedReader(in);
String line;
while ((line = buff.readLine()) != null) {
text.append(line + "\n");
}
Log.d("Runnable", "After IO call:"+ text.toString());
Message msg = new Message();
msg.obj = text.toString();
responseHandler.sendMessage(msg);
} catch (Exception err) {
err.printStackTrace();
}
}
};
requestHandler.post(myRunnable);
有用的文章:
handlerthreads-and-why-you-should-be-using-them-in-your-android-apps
android-looper-handler-handlerthread-i
其他回答
Kotlin 版本
当你在做某项活动时,就用
runOnUiThread {
//code that runs in main
}
当你有活动上下文,mContext然后使用
mContext.runOnUiThread {
//code that runs in main
}
当你在一个没有上下文的地方,然后使用
Handler(Looper.getMainLooper()).post {
//code that runs in main
}
压缩代码块如下所示:
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
// things to do on the main thread
}
});
这并不涉及传递活动引用或应用程序引用。
芬兰湾的科特林相当于:
Handler(Looper.getMainLooper()).post(Runnable {
// things to do on the main thread
})
最简单的方法,特别是如果你没有context,如果你在使用RxAndroid,你可以这样做:
AndroidSchedulers.mainThread().scheduleDirect {
runCodeHere()
}
使用Kotlin,在任何函数中都是这样的:
runOnUiThread {
// Do work..
}
如果你在线程中运行代码,例如延迟一些动作,那么你需要从上下文调用runOnUiThread。例如,如果你的代码在MainActivity类中,那么使用这个:
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
myAction();
}
});
如果你的方法可以从main (UI线程)或其他线程调用,你需要像这样检查:
public void myMethod() {
if( Looper.myLooper() == Looper.getMainLooper() ) {
myAction();
}
else {
}