Ahm*_*med 302 java multithreading android android-handler
在android服务中,我创建了一些用于执行某些后台任务的线程.
我有一种情况,线程需要在主线程的消息队列上发布某些任务,例如a Runnable.
有没有办法获得Handler主线程并从我的其他线程发布Message/ Runnable到它?
谢谢,
Dav*_*ser 593
注意:这个答案引起了很多关注,我需要更新它.自从原始答案发布以来,@ dzeikei的评论几乎与原始答案一样受到关注.这里有两种可能的解决方案:
1.如果您的后台线程具有Context对象的引用:
确保后台工作线程有权访问Context对象(可以是Application上下文或Service上下文).然后在后台工作线程中执行此操作:
// Get a handler that can be used to post to the main thread
Handler mainHandler = new Handler(context.getMainLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {....} // This is your code
};
mainHandler.post(myRunnable);
Run Code Online (Sandbox Code Playgroud)
2.如果您的后台线程没有(或不需要)Context对象
(由@dzeikei建议):
// Get a handler that can be used to post to the main thread
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {....} // This is your code
};
mainHandler.post(myRunnable);
Run Code Online (Sandbox Code Playgroud)
小智 136
正如下面的评论者所指出的,这不是服务的一般解决方案,仅适用于从您的活动启动的线程(服务可以是这样的线程,但不是所有这些线程).关于服务活动沟通的复杂主题,请阅读官方文档的整个服务部分 - 它很复杂,因此理解基础知识是值得的:http: //developer.android.com/guide/components/services.html #Notifications
以下方法可以在最简单的情况下工作.
如果我理解正确,你需要在应用程序的GUI线程中执行一些代码(不能考虑其他任何称为"主"线程).为此,有一种方法Activity:
someActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
//Your code to run in GUI thread here
}//public void run() {
});
Run Code Online (Sandbox Code Playgroud)
Doc:http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29
希望这是你正在寻找的.
tem*_*man 30
如果您无法访问Context,还有另一种简单的方法.
1).从主循环器创建一个处理程序:
Handler uiHandler = new Handler(Looper.getMainLooper());
Run Code Online (Sandbox Code Playgroud)
2).实现Runnable接口:
Runnable runnable = new Runnable() { // your code here }
Run Code Online (Sandbox Code Playgroud)
3).将Runnable发布到uiHandler:
uiHandler.post(runnable);
Run Code Online (Sandbox Code Playgroud)
这就是全部;-)享受线程的乐趣,但不要忘记同步它们.
Ale*_*kov 28
如果您在一个线程中运行代码,例如延迟某些操作,那么您需要runOnUiThread从上下文中调用.例如,如果您的代码在MainActivity类中,那么使用:
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
myAction();
}
});
Run Code Online (Sandbox Code Playgroud)
如果您的方法可以从main(UI线程)或其他线程调用,则需要检查:
public void myMethod() {
if( Looper.myLooper() == Looper.getMainLooper() ) {
myAction();
}
else {
}
Run Code Online (Sandbox Code Playgroud)
dav*_*lee 21
精简代码块如下:
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
// things to do on the main thread
}
});
Run Code Online (Sandbox Code Playgroud)
这不涉及传递Activity引用或Application引用.
Kotlin等效物:
Handler(Looper.getMainLooper()).post(Runnable {
// things to do on the main thread
})
Run Code Online (Sandbox Code Playgroud)
我知道这是一个老问题,但我遇到了一个在 Kotlin 和 Java 中都使用的主线程单行代码。这可能不是服务的最佳解决方案,但对于调用会更改片段内部 UI 的内容来说,这是非常简单和明显的。
爪哇 (8):
getActivity().runOnUiThread(()->{
//your main thread code
});
Run Code Online (Sandbox Code Playgroud)
科特林:
this.runOnUiThread {
//your main thread code
}
Run Code Online (Sandbox Code Playgroud)
When you are on an activity, then use
runOnUiThread {
//code that runs in main
}
Run Code Online (Sandbox Code Playgroud)
When you have activity context, mContext then use
mContext.runOnUiThread {
//code that runs in main
}
Run Code Online (Sandbox Code Playgroud)
When you are in somewhere where no context available, then use
Handler(Looper.getMainLooper()).post {
//code that runs in main
}
Run Code Online (Sandbox Code Playgroud)
HandlerThread是 Android 中普通 java 线程的更好选择。
requestHandlerpost一项Runnable任务requestHandler与 UI 线程的通信来自HandlerThread
Handler并覆盖方法LooperresponseHandlerhandleMessageRunnable任务(HandlerThread在本例中),sendMessage调用responseHandlersendMessage结果调用handleMessagein responseHandler。Message并处理它,更新 UI示例:TextView使用从 Web 服务接收的数据进行更新。由于 Web 服务应该在为网络操作创建的非 UI 线程上调用HandlerThread。从 Web 服务获取内容后,将消息发送到主线程(UI 线程)处理程序,该处理程序Handler将处理该消息并更新 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);
Run Code Online (Sandbox Code Playgroud)
有用的文章:
处理程序线程以及为什么你应该在你的 Android 应用程序中使用它们
android-looper-handler-handlerthread-i
最简单的方法,尤其是在没有上下文的情况下,如果您使用的是 RxAndroid,则可以执行以下操作:
AndroidSchedulers.mainThread().scheduleDirect {
runCodeHere()
}
Run Code Online (Sandbox Code Playgroud)
使用 handler 更精确的 Kotlin 代码:
Handler(Looper.getMainLooper()).post {
// your codes here run on main Thread
}
Run Code Online (Sandbox Code Playgroud)
ContextCompat.getMainExecutor(context).execute {
// do something
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
251475 次 |
| 最近记录: |