是否可以在BroadcastReceiver中的onReceive方法中退出looper

时间:2014-10-29 04:52:42

标签: android broadcastreceiver android-looper

使用以下代码并在onReceive被触发时,收到以下错误

Error receiving broadcast Intent { act=com.sample.service.ReminderActivityService flg=0x10 (has extras) } 
com.sample.common.UserActivity$1@41c2b4b0

中的

问题是这句话Looper.myLooper().quit(); 如何在收到以下代码中的广播后终止looper

public class UserActivity extends Thread implements
    ConnectionCallbacks, OnConnectionFailedListener {

private String TAG;
// Constants that define the activity detection interval
public static final int MILLISECONDS_PER_SECOND = 1000;
public static final int DETECTION_INTERVAL_SECONDS = 30;
public static final int DETECTION_INTERVAL_MILLISECONDS = MILLISECONDS_PER_SECOND * DETECTION_INTERVAL_SECONDS;
IntentService is;
onActivityGot mCallback;
Handler mHandler;
Context mContext;
BroadcastReceiver br;
/*
 * Store the PendingIntent used to send activity recognition events
 * back to the app
 */
private PendingIntent mActivityRecognitionPendingIntent;
// Store the current activity recognition client
private ActivityRecognitionClient mActivityRecognitionClient;

public UserActivity(UserActivity.onActivityGot ints) {
    is = (IntentService) ints;
    mContext = is.getApplicationContext();
    mHandler = new Handler();
    TAG = this.getClass().getSimpleName();
    // This makes sure that the container service has implemented
    // the callback interface. If not, it throws an exception
    try {
        mCallback = (UserActivity.onActivityGot) ints;
    } catch (ClassCastException e) {
        throw new ClassCastException(ints.toString()
                + " must implement UserActivity.onActivityGot");
    }
    Log.i(TAG, "UserActivity constractor fired in activity");
}

@Override
public void run() {
    if (servicesConnected()) {
        Looper.prepare();
        Log.i(TAG, "servicesConnected fired in activity");
        /*
         * Instantiate a new activity recognition client. Since the
         * parent Activity implements the connection listener and
         * connection failure listener, the constructor uses "this"
         * to specify the values of those parameters.
         */
        mActivityRecognitionClient =
                new ActivityRecognitionClient(mContext, this, this);
        // connect to the service
        mActivityRecognitionClient.connect();

        br = new BroadcastReceiver() {
            @Override
            public void onReceive(Context c, Intent i) {
                //call calback with data
                mCallback.activityKnown(i);
                mActivityRecognitionClient.removeActivityUpdates(mActivityRecognitionPendingIntent);
                mActivityRecognitionClient.disconnect();
                mContext.unregisterReceiver(br);
                Looper.myLooper().quit();
            }
        };
        mContext.registerReceiver(br, new IntentFilter("com.sample.service.ReminderActivityService"));
        Looper.loop();
    }
}

@Override
public void onConnected(Bundle dataBundle) {
    Log.i(TAG, "onConnected fired");
    /*
     * Create the PendingIntent that Location Services uses
     * to send activity recognition updates back to this app.
     */
    Intent intent = new Intent(
            mContext, ReminderActivityService.class);
    /*
     * Return a PendingIntent that starts the IntentService.
     */
    mActivityRecognitionPendingIntent =
            PendingIntent.getService(mContext, 0, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);
    /*
     * Request activity recognition updates using the preset
     * detection interval and PendingIntent. This call is
     * synchronous.
     */
    mActivityRecognitionClient.requestActivityUpdates(
            DETECTION_INTERVAL_MILLISECONDS,
            mActivityRecognitionPendingIntent);
}

@Override
public void onDisconnected() {
    // Delete the client
    mActivityRecognitionClient = null;
    Looper.myLooper().quit();
    Log.i(TAG, "onDisconnected fired");
}

@Override
public void onConnectionFailed(ConnectionResult cr) {
    mHandler.post(new UiToastCommunicaton(mContext,
            is.getResources().getString(R.string.action_connfailed)));
    mCallback.activityFail();
    Looper.myLooper().quit();
    Log.i(TAG, "onConnectionFailed fired");
}

private boolean servicesConnected() {
    // Check that Google Play services is available
    int resultCode =
            GooglePlayServicesUtil.
            isGooglePlayServicesAvailable(is.getBaseContext());

    if (ConnectionResult.SUCCESS == resultCode) {// If Google Play services is available
        // In debug mode, log the status
        Log.d("Activity Recognition",
                "Google Play services is available.");
        // Continue
        return true;

    } else {// Google Play services was not available for some reason
        mHandler.post(new UiToastCommunicaton(mContext,
                is.getResources().getString(R.string.gpserv_notfound)));
        return false;
    }
}

public interface onActivityGot {

    public void activityKnown(Intent i);

    public void activityFail();
}
}

1 个答案:

答案 0 :(得分:0)

通过在静态变量中存储looper的句柄找到了一种方法。查看以下内容。

声明变量

public static Handler looperHandle;

在准备looper

之后设置变量
 Looper.prepare();
    looperHandle = new Handler();

因为我在一个名为

的对象中实例化了这个类
 object.looperHandle.getLooper().quit();
由于使用静态变量,我对此解决方案不满意。 如果有人有更好的解决方案,请在此处发布。