无法在未调用 Looper 准备的线程内创建处理程序 [重复]

Posted

技术标签:

【中文标题】无法在未调用 Looper 准备的线程内创建处理程序 [重复]【英文标题】:Can't create handler inside thread that has not called Looper prepare [duplicate] 【发布时间】:2016-10-31 10:56:02 【问题描述】:
public class MyCustomService extends Service 
    private WindowManager windowManager;
    private ImageView chatHead;
    WindowManager.LayoutParams params;
    private static Context mContext;

    IBinder mBinder = new LocalBinder();

    public static Socket client;

    @Override
    public IBinder onBind(Intent intent) 
        return mBinder;
    

    public class LocalBinder extends Binder 
        public MyCustomService getServerInstance() 
            return MyCustomService.this;
        
    

    // Fires when a service is first initialized
    public void onCreate() 
        super.onCreate();
        this.mContext = this;

        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    

    // Fires when a service is started up
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
        IO.Options opts = new IO.Options();
        opts.query = "auth_token=51";
        try 
            client = IO.socket("http://192.168.0.106:3000/",opts);
            client.on("message", onMessage);

            client.connect();
        
        catch (URISyntaxException e) 
            e.printStackTrace();
        

        return START_STICKY;
    

    @Override
    public void onDestroy() 
        client.disconnect();
        client.close();
        if (chatHead != null) windowManager.removeView(chatHead);
    

    public void addView()
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    
        chatHead = new ImageView(mContext);
        chatHead.setImageResource(R.drawable.android_head);
    
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.TOP | Gravity.LEFT;
        params.x = 0;
        params.y = 100;

        windowManager.addView(chatHead, params);
    

    private Emitter.Listener onMessage = new Emitter.Listener() 
        @Override
        public void call(Object... args) 
            addView();
        
    ;

我想从服务中创建警报窗口。当我从服务的onCreate 方法调用函数addView 时,它可以正常工作。

onMessage 方法在我向套接字发送新数据时被调用。所以我只想在收到来自套接字的消息时显示警报窗口,但如果我从 onMessage 函数调用函数 addView,它会给我一个错误:

无法在未调用 Looper.prepare() 的线程内创建处理程序

但如果我从服务的onCreate 方法调用它,它就可以工作。

【问题讨论】:

【参考方案1】:

public void call(Object... args) 不是从 UI 线程调用的。您可以通过Handler 做到这一点。

Handler mHandler = new Handler(Looper.getMainLooper());
...
...
...
private Emitter.Listener onMessage = new Emitter.Listener() 

   @Override
   public void call(Object... args) 

      mHandler.post(new Runnable()

         @Override
         public void run ()
         addView();
         
     );
;

【讨论】:

以上是关于无法在未调用 Looper 准备的线程内创建处理程序 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

无法在未调用 Looper 的线程内创建处理程序 [重复]

无法在未调用 Looper.prepare()3 的线程内创建处理程序

无法在未调用 Looper.prepare() 的线程内创建处理程序

无法在未调用 Looper.prepare() 的线程内创建处理程序

无法在未调用 Looper.prepare() Graphhopper 的线程内创建处理程序

无法在未调用 Looper.prepare()-Alertdialogbox 的线程内创建处理程序 [重复]