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. 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 に答える