0

我正在开发一个 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);
}

我究竟做错了什么?

4

3 回答 3

3

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

2.让 UI 工作在 UI 线程上被认为是好的做法,而 Non-UI 工作在 Non-UI 线程上,但从HoneyComb 开始,它变成了一种规则

3.所以对于你的后台线程使用Thread will Handler,或者AsyncTask。

4. Non-UI work are executed on the foreground using Handler, which in turn requires UI thread to call Looper.loop() to get the actual messages serviced, So there is no need to explicitly call Looper.loop() or prepare().

于 2012-07-04T07:41:14.313 回答
1

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

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

也许你可以看看HandlerThread

于 2012-07-04T07:21:10.877 回答
1

首先,Service不在后台线程上运行,因此您应该使用 a Thread、 anAsyncTask或 anIntentService来进行后台工作。其次,Service已经初始化了 Looper,您必须从代码中删除Looper.prepare()和。Looper.loop()

于 2012-07-04T07:24:07.217 回答