1

我在其中使用 Service 和 AsyncTask 时遇到了一点问题。我编写了一个做一些 HTTP 工作的小类,它执行一个 AsyncTask 以在后台完成所有 HTTP 工作,当它完成时,它用响应数据调用一个侦听器。

现在我需要在服务(远程服务)中使用该类,并且每次该类尝试从 AsyncTask 类创建一个对象时,它都会崩溃并在日志 cat 中显示以下消息:

05-07 10:30:01.847: E/JavaBinder(1026): *** Uncaught remote exception!  (Exceptions are not yet supported across processes.)
05-07 10:30:01.847: E/JavaBinder(1026): java.lang.ExceptionInInitializerError
05-07 10:30:01.847: E/JavaBinder(1026):     at com.lowlevel.umusic.VK.getById(VK.java:46)
05-07 10:30:01.847: E/JavaBinder(1026):     at com.lowlevel.umusic.Song.requestUri(Song.java:109)
05-07 10:30:01.847: E/JavaBinder(1026):     at com.lowlevel.umusic.PlayService$1.playSong(PlayService.java:149)
05-07 10:30:01.847: E/JavaBinder(1026):     at com.lowlevel.umusic.IPlayService$Stub.onTransact(IPlayService.java:55)
05-07 10:30:01.847: E/JavaBinder(1026):     at android.os.Binder.execTransact(Binder.java:320)
05-07 10:30:01.847: E/JavaBinder(1026):     at dalvik.system.NativeStart.run(Native Method)
05-07 10:30:01.847: E/JavaBinder(1026): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-07 10:30:01.847: E/JavaBinder(1026):     at android.os.Handler.<init>(Handler.java:121)
05-07 10:30:01.847: E/JavaBinder(1026):     at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
05-07 10:30:01.847: E/JavaBinder(1026):     at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
05-07 10:30:01.847: E/JavaBinder(1026):     at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
05-07 10:30:01.847: E/JavaBinder(1026):     ... 6 more
05-07 10:30:01.847: W/dalvikvm(1026): threadid=8: thread exiting with uncaught exception (group=0x40015560)
05-07 10:30:01.847: E/AndroidRuntime(1026): FATAL EXCEPTION: Binder Thread #2
05-07 10:30:01.847: E/AndroidRuntime(1026): java.lang.ExceptionInInitializerError
05-07 10:30:01.847: E/AndroidRuntime(1026):     at com.lowlevel.umusic.VK.getById(VK.java:46)
05-07 10:30:01.847: E/AndroidRuntime(1026):     at com.lowlevel.umusic.Song.requestUri(Song.java:109)
05-07 10:30:01.847: E/AndroidRuntime(1026):     at com.lowlevel.umusic.PlayService$1.playSong(PlayService.java:149)
05-07 10:30:01.847: E/AndroidRuntime(1026):     at com.lowlevel.umusic.IPlayService$Stub.onTransact(IPlayService.java:55)
05-07 10:30:01.847: E/AndroidRuntime(1026):     at android.os.Binder.execTransact(Binder.java:320)
05-07 10:30:01.847: E/AndroidRuntime(1026):     at dalvik.system.NativeStart.run(Native Method)
05-07 10:30:01.847: E/AndroidRuntime(1026): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-07 10:30:01.847: E/AndroidRuntime(1026):     at android.os.Handler.<init>(Handler.java:121)
05-07 10:30:01.847: E/AndroidRuntime(1026):     at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
05-07 10:30:01.847: E/AndroidRuntime(1026):     at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
05-07 10:30:01.847: E/AndroidRuntime(1026):     at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
05-07 10:30:01.847: E/AndroidRuntime(1026):     ... 6 more

有什么想法,或者我必须修改我的课程以同步工作?

谢谢!

4

2 回答 2

1

我回答我自己的问题,希望它可以帮助正在尝试相同问题并找到此消息的其他人。

AsyncTask 可以在服务中使用,但不能在存根中使用。就如此容易。

如果您需要从存根调用它们,有几种方法可以让它们工作:

1.示例代码:

public class MyService extends Service {
    private static final int MSG_CALLTASK = 0;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MSG_CALLTASK:
                new MyAsyncTask().execute();
                break;
            }
        }
    };

    private IMyService.Stub mStub = new IMyService.Stub = {
        public void myFunction() {
            /* Call task */
            mHandler.sendMessage(mHandler.obtainMessage(MSG_CALLTASK));
        }
    };

    [...]
}

2.第二种方法是避免从存根调用方法,只向服务发送一个意图并在'onStartCommand'方法中解析它(发送意图时会调用它)。

我希望这是有帮助的!

于 2013-04-27T13:14:17.713 回答
0
public class LoginService_Service extends Service {
    NotificationManager mNM;
    static String stcode="";

    @Override
    public void onCreate() {
        mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        new DoLogin().execute(null);
    }
    @Override
    public void onDestroy() {
        mNM.cancel(R.string.notify_cancel);
        Log.i("Finish", "OnDestroy Called");
    }

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

    private final IBinder mBinder = new Binder() {
        @Override
        protected boolean onTransact(int code, Parcel data, Parcel reply,
                int flags) throws RemoteException {
            return super.onTransact(code, data, reply, flags);
        }
    };
    public class DoLogin extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            HttpClient client = new DefaultHttpClient();
            HttpConnectionParams
                    .setConnectionTimeout(client.getParams(), 10000); // Timeout
            try {
                HttpPost request = new HttpPost(
                        "myurl");
                JSONStringer jsonstr = new JSONStringer().object().key(
                "UserName").value(prefs.getString("unm", "")).key(
                "Password").value(prefs.getString("pwd", ""))
                .endObject();

                Log.i("JSONStringer", jsonstr.toString());
                StringEntity entity = new StringEntity(jsonstr.toString());
                entity.setContentType("application/json;charset=UTF-8");// text/plain;charset=UTF-8
                entity
                        .setContentEncoding(new BasicHeader(
                                HTTP.CONTENT_TYPE,
                                "application/json;charset=UTF-8"));
                request.setEntity(entity);
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpResponse res = httpClient.execute(request);
                Log.i("Request", request.toString());
            } catch (Exception e) {
                e.printStackTrace();
                Log.i("Error", "Cannot Estabilish Connection");
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            if (stcode != null) {
                if (stcode.equalsIgnoreCase("0")) {
                    Log.i("ReLogin", "ReLogin Success");
                } else {
                    Log.i("ReLogin", "ReLogin Failed");
                }
            }
            LoginService_Service.this.stopSelf();
        }

    }
}
于 2012-05-07T14:21:13.167 回答