无法创建服务“每个线程只能创建一个Looper”

时间:2012-07-04 07:02:04

标签: android service

我正在开发Android 3.1平板电脑应用程序。

这个应用程序将运行一个线程。在服务上,我有以下代码:

public class UDPSocketBackgroundService extends Service
{

@Override
public void onCreate()
{
    super.onCreate();
    Log.v(TAG, "in onCreate()");

    // xxxxxx
    Looper.prepare();
    mServiceHandler = new Handler() {
        /**
         * 
         */
        public void handleMessage(Message msg)
        {
            DatagramPacket packet = (DatagramPacket) msg.obj;
            //String received = new String(packet.getData(), 0, packet.getLength());

            Message backMsg = Message.obtain();
            backMsg.arg1 = Activity.RESULT_OK;;

            Bundle bundle = new Bundle();
            bundle.putByteArray("CLIENT_DATA", packet.getData());
            bundle.putString("CLIENT_HOST", packet.getAddress().getHostAddress());
            bundle.putString("CLIENT_PORT", new Integer(packet.getPort()).toString());
            backMsg.setData(bundle);

            try
            {
                outMessenger.send(backMsg);
            }
            catch (android.os.RemoteException e1)
            {
                Log.w(getClass().getName(), "Exception sending message", e1);
            }
        }
    };
    Looper.loop();
}

但我不知道为什么(因为这是我第一次使用服务)我在这里得到一个例外:

Looper.prepare();

更新

服务的onBind活动:

public IBinder onBind(Intent intent)
{
    Bundle extras = intent.getExtras();
    // Get messager from the Activity
    if (extras != null) {
        outMessenger = (Messenger) extras.get("MESSENGER");
    }

    try
    {
        myThread = new UDPServerThread("X", 8888, mServiceHandler);
        myThread.start();
    }
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return mMessenger.getBinder();
}

这是我如何从主活动启动服务:

protected void onResume()
{
    super.onResume();

    Intent intent = null;
    intent = new Intent(this, UDPSocketBackgroundService.class);
    // Create a new Messenger for the communication back
    // From the Service to the Activity
    Messenger messenger = new Messenger(handler);
    intent.putExtra("MESSENGER", messenger);

    bindService(intent, conn, Context.BIND_AUTO_CREATE);
}

我做错了什么?

3 个答案:

答案 0 :(得分:2)

1。服务不在后台线程上运行,而是在专用UI线程上运行。

2。在UI线程上使用UI工作是非常好的做法,非UI在非UI线程上工作,但是来自HoneyComb的成为规则

3. 因此,对于您的后台线程,请使用Thread will Handler或AsyncTask。

4。使用Handler在前台执行非UI工作,而后者需要UI线程调用Looper.loop()以获取服务的实际消息 ,所以无需显式调用 Looper.loop()或prepare()。

答案 1 :(得分:1)

服务在UI线程上运行,并且UI线程已经有一个looper,这就是你收到错误的原因。

如果您打算在后台线程中完成工作,那么您可能需要为要运行的代码创建一个新线程。

也许您可以查看HandlerThread

答案 2 :(得分:1)

首先,Service不会在后台线程上运行,因此您应该使用ThreadAsyncTaskIntentService作为后台工作。其次,Service已经初始化了一个Looper,您必须从代码中删除Looper.prepare()Looper.loop()