【问题标题】:Can't create handler inside thread that has not called Looper prepare [duplicate]无法在未调用 Looper 准备的线程内创建处理程序 [重复]
【发布时间】: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 方法调用它,它就可以工作。

【问题讨论】:

    标签: java android


    【解决方案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();
             }
         });
    };
    

    【讨论】:

      猜你喜欢
      • 2013-08-30
      • 1970-01-01
      • 2012-11-27
      • 2012-10-01
      • 1970-01-01
      • 2012-08-15
      • 1970-01-01
      • 2011-09-06
      相关资源
      最近更新 更多