7

別のプロセスで開始するように設定されたサービスがあります。

<service android:name=".services.UploadService"
          android:process=":UploadServiceProcess" />

そして、bindService() を使用して正常にバインドできます。Messenger.send() を呼び出してメッセージを送信しようとすると、問題が発生します。

service.send(Message.obtain(null, UploadService.MESSAGE_UPLOAD_REQUEST, uploadRequest));

ここで、uploadRequest は Parcelable を実装するカスタム オブジェクトです。

public class UploadRequest implements Parcelable {
    public File file;
    public boolean deleteOnUpload;

public UploadRequest(File file, boolean deleteOnUpload) {
    this.file = file;
    this.deleteOnUpload = deleteOnUpload;
}

private UploadRequest(Parcel in) {
    this.file = new File(in.readString());
}

public int describeContents() {
    return 0;
}

public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(this.file.getPath());
}

public static final Parcelable.Creator<UploadRequest> CREATOR = new Parcelable.Creator<UploadRequest>() {
    public UploadRequest createFromParcel(Parcel in) {
        return new UploadRequest(in);
    }
    public UploadRequest[] newArray(int size) {
        return new UploadRequest[size];
    }
};

}

サービスの handleMessage にブレークポイントを設定しましたが、アプリがブレークポイントに到達しません。ただし、カスタム UploadRequest オブジェクトを使用する代わりに null を送信すると、期待どおりに handleMessage ブレークポイントに到達しますが、明らかにその時点では何もできません。writeToParcel を呼び出すと null 以外の文字列が返される場合に file.getPath() を確認しました。これにより、UploadRequest クラスで何かがおかしいと思われますが、グーグルで調べてもクラスに問題はありません。何か案は?

4

3 に答える 3

13

Message メンバー objのドキュメントには、次のように書かれています。

受信者に送信する任意のオブジェクト。Messenger を使用してプロセス間でメッセージを送信する場合、フレームワーク クラス (アプリケーションによって実装されたものではない) の Parcelable が含まれている場合にのみ、これは非 null になります。その他のデータ転送には setData(Bundle) を使用します。ここでの Parcelable オブジェクトは、FROYO リリースより前ではサポートされていないことに注意してください。

私の推測では、プロセスの境界を越えるときに許可されていない独自のパーセルブルを作成しているため、問題が発生していると思います。代わりに、オブジェクトをバンドルにパッケージ化する必要があります。これは、オブジェクトが Serializable を実装する必要があることも意味しますが、Parcelable である必要はありません。

于 2011-02-24T05:04:42.690 に答える
4

今これを試しました。

Message.obj は、ContentValues などのフレームワーク クラスを転送できます。

Message.SetData はバンドルをプロセス間で転送でき、任意の Parcelable オブジェクトをバンドルに入れることができます。

Messag を受信したら、バンドルで setClassLoader を呼び出すことを忘れないでください。

送信側

        Message localMsg = Message.obtain();
        localMsg.what = TPServiceConnection.MSG_REPLY_SERVICE_HELLO;

        Bundle data = new Bundle();

        ContentValues cv = new ContentValues();
        cv.put("KEY", mRand.nextInt());
        data.putParcelable("KEY", cv);

        TPServiceDataModal modal = new TPServiceDataModal(mRand.nextInt());
        data.putParcelable("KEY2", modal);

        localMsg.setData(data);

受け取る側

        Bundle data = msg.getData();
        data.setClassLoader(this.getClass().getClassLoader());

        Parcelable parcelable = data.getParcelable("KEY");
        if (parcelable instanceof ContentValues) {
            ContentValues cv = (ContentValues) parcelable;
            Log.d(TAG, "reply content: " + cv.getAsInteger("KEY"));
        }

        Parcelable parcelable2 = data.getParcelable("KEY2");
        if (parcelable2 instanceof TPServiceDataModal) {
            TPServiceDataModal modal = (TPServiceDataModal) parcelable2;
            Log.d(TAG, "reply modal: " + modal.mData);
        }

ここで、TPServiceDataModal は Parcelable 呼び出しです。

于 2014-12-17T05:56:25.570 に答える