简体   繁体   English

android - 从工作线程调用ui线程

[英]android - calling ui thread from worker thread

Hi I want to make Toast available to me no-matter-what and available from any thread whenever I like within my application. 嗨,我想在我的应用程序中随时随地通过任何线程向我提供Toast So to do this I extended the Activity class: 所以为了做到这一点,我扩展了Activity类:

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;

public class MyActivity extends Activity{
    private Handler mHandler;

    @Override   
    public void onCreate(Bundle savedInstanceState) {       
        mHandler = new Handler();
        super.onCreate(savedInstanceState);
    }

    private class ToastRunnable implements Runnable {
        String mText;

        public ToastRunnable(String text) {
            mText = text;
        }

        public void run(){
           Toast.makeText(getApplicationContext(), mText, Toast.LENGTH_SHORT).show();
        }
    }

    public void doToast(String msg) {
        mHandler.post(new ToastRunnable(msg));
    }
}

so that all Activity classes in my app are now simply 所以我的应用程序中的所有 Activity类现在都是简单的

public class AppMain extends MyActivity {
   //blah
}

what I expected to be able to do (in a worker thread) was this: 我期望能够做到的(在工作线程中)是这样的:

try{
   MyActivity me = (MyActivity) Looper.getMainLooper().getThread();
   me.doToast("Hello World");
}
catch (Exception ex){
   Log.e("oh dear", ex.getMessage());
}

and so long as the Activity was a " MyActivity " it should work - but the problem is ---> the Looper.getMainLooper().getThread(); 只要Activity是一个“ MyActivity ”它应该工作 - 但问题是---> Looper.getMainLooper().getThread(); isn't returning the MyActivity to me and it's making me cry - what am I doing wrong? 没有将MyActivity给我,这让我哭了 - 我做错了什么?

: EDIT : :编辑:

some background to explain "why" I am stuck with this type of implmentation. 一些背景解释“为什么”我坚持这种类型的implmentation。

I need to be able to confirm to the user that a "HTTP POST" event has been a success. 我需要能够向用户确认“HTTP POST”事件是否成功。 Now. 现在。 If the User clicks "OK" on the UI Form it MAY or MAY NOT have internet at that time.. If it has Internet - all well and good - it posts the form via HTTP POST all well and good .. but if there is NO Internet most (99.999% of Android apps lame /pathetic / mewling at this, and basically offer the user no plan "b" assuming that at all times the internet is there - when it is NOT) 如果用户点击UI表单上的“确定”它当时可能或者可能没有互联网..如果它有互联网 - 一切都很好 - 它通过HTTP POST发布表格一切都很好 ......但是如果有的话没有互联网最多(99.999%的Android应用程序跛足/可怜/ mewling在这,并基本上提供用户没有计划“b”假设在任何时候互联网都在那里 - 当它不是)

My App will not "go lame (as I call it)" - it does have a plan "b" instead it "Queues" the post event and retries every x minutes.. now this is a silent thread in the background.. I have plenty of user interaction all over the app I don't know where the user will "be" but eventually when the HTTP POST that queue/retries/queue/retries returns "! Success! " I want to Toast that as a message to the user (EG: "your form was sent") 我的应用程序不会“跛脚(我称之为)” - 它确实有一个计划“b”而不是“队列”发布事件并重试每x分钟..现在这是一个背景中的无声线程..我在整个应用程序中有大量的用户交互我不知道用户将在哪里“但”最终当队列/重试/队列/重试的HTTP POST返回“!成功!”我想要作为消息Toast用户(EG:“您的表格已发送”)

What's wrong with runOnUiThread ? runOnUiThread什么问题?

http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable ) http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable

activity.runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(activity, "Hello, world!", Toast.LENGTH_SHORT).show();
    }
});

use below code. 使用下面的代码。 create activity object which contains your activity instance.. 创建包含活动实例的活动对象。

activity.runOnUiThread(new Runnable() {
  public void run() {
    Toast.makeText(activity.getApplicationContext(),"Toast text",Toast.LENGTH_SHORT).show();
  }
);

This will allow you to display the message without needing to rely on the context to launch the toast, only to reference when displaying the message itself. 这将允许您显示消息,而无需依赖上下文来启动Toast,仅在显示消息本身时引用。

runOnUiThread was not working from an OpenGL View thread and this was the solution. runOnUiThread无法在OpenGL View线程中运行,这就是解决方案。 Hope it helps. 希望能帮助到你。

private Handler handler = new Handler();
handler.post(new Runnable() {
    public void run() {
        Toast.makeText(activity, "Hello, world!", Toast.LENGTH_SHORT).show();
    }
});

You can't just cast the result of getThread() to an instance of your MyActivity base class. 您不能只将getThread()的结果MyActivityMyActivity基类的实例。 getThread() returns a Thread which has nothing to do with Activity . getThread()返回一个与Activity无关的Thread

There's no great -- read: clean -- way of doing what you want to do. 没有伟大的阅读:干净 - 做你想做的事情的方式。 At some point, your "worker thread" abstraction will have to have a reference to something that can create a Toast for you. 在某些时候,你的“工人线程”抽象必须引用一些可以为你创建Toast的东西。 Saving off some static variable containing a reference to your Activity subclass simply to be able to shortcut Toast creation is a recipe for memory leaks and pain. 保存一些包含对Activity子类的引用的静态变量只是为了能够快速创建Toast是内存泄漏和痛苦的一个方法。

Why don't you send an intent that is captured by a BroadCastReceiver, then the broadcast receiver can create a notification in the notification tray. 为什么不发送BroadCastReceiver捕获的意图,然后广播接收器可以在通知托盘中创建通知。 It's not a toast, but its a way to inform the user that his post has been successful. 这不是祝酒,而是告诉用户他的帖子成功的一种方式。

如果它在你自己的活动中,为什么你不能只调用doToast()

if you have the context with you, you can call the ui thread like this from non activity class. 如果你有上下文,你可以从非活动类调用这样的ui线程。

((Activity)context).runOnUiThread(new Runnable() {
    public void run() {
        // things need to work on ui thread
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM