一段时间后Android小部件无响应

3

我开发了一个带有小部件的简单手电筒。但是在一段时间后,出现了奇怪的情况,小部件不再响应。添加新部件时一切正常,但旧部件应该被删除。

public class XFlashLightAppWidgetProvider extends AppWidgetProvider {

/** Action name for updating widget receiver */
private static final String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {
    // Loop through all widgets of this application
    for (int i = 0; i < appWidgetIds.length; i++) {
        // Creating intent to send to the widget broadcast receiver
        // with update action
        Intent intent = new Intent(context,
                XFlashLightAppWidgetProvider.class);
        intent.setAction(ACTION_WIDGET_RECEIVER);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
                0, intent, 0);

        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.appwidget);

        // When user click on the widget - send broadcast intent to the
        // widget
        // broadcast receiver for enabling or disabling flashlight and
        // updating widgets
        views.setOnClickPendingIntent(R.id.widgetLampImage, pendingIntent);

        // When user added new widget on his device - checking flashlight
        // and if flashlight is enabled - changing widget icon
        if (CameraHelper.isTorchFlashMode()) {
            views.setImageViewResource(R.id.widgetLampImage,
                    R.drawable.widget_on);
        }

        // Update each widget of the application
        appWidgetManager.updateAppWidget(appWidgetIds[i], views);
    }
    super.onUpdate(context, appWidgetManager, appWidgetIds);
}

@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    // Check whether the device supports flash on the camera and the
    // receiver
    // received correct action
    if (CameraHelper.checkCameraFlashLightHadrware(context)
            && (action.equals(ACTION_WIDGET_RECEIVER)
                    || action.equals(XFlashLightActivity.ACTION_WIDGET_ON) || action
                        .equals(XFlashLightActivity.ACTION_WIDGET_OFF))) {
        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.appwidget);

        // Checking action name, if action name equals
        // "ActionReceiverWidget" -
        // enable or disable flashlight and update widget icon, else if
        // action name
        // equals "ActionReceiverOn" or "ActionReceiverOff" - change widget
        // icon only
        if (action.equals(ACTION_WIDGET_RECEIVER)) {
            if (!CameraHelper.isTorchFlashMode()) {
                CameraHelper.initializeCameraFlash();
                views.setImageViewResource(R.id.widgetLampImage,
                        R.drawable.widget_on);
            } else {
                CameraHelper.releaseCamera();
                views.setImageViewResource(R.id.widgetLampImage,
                        R.drawable.widget_off);
            }
        } else if (action.equals(XFlashLightActivity.ACTION_WIDGET_ON)) {
            views.setImageViewResource(R.id.widgetLampImage,
                    R.drawable.widget_on);
        } else if (action.equals(XFlashLightActivity.ACTION_WIDGET_OFF)) {
            views.setImageViewResource(R.id.widgetLampImage,
                    R.drawable.widget_off);
        }

        // Update each widget of the application
        AppWidgetManager appWidgetManager = AppWidgetManager
                .getInstance(context);
        int[] appWidgetIds = appWidgetManager
                .getAppWidgetIds(new ComponentName(context,
                        XFlashLightAppWidgetProvider.class.getName()));
        for (int i = 0; i < appWidgetIds.length; i++) {
            appWidgetManager.updateAppWidget(appWidgetIds[i], views);
        }
    }
    super.onReceive(context, intent);
  }
}
2个回答

1

当Android面临低内存情况时,它会停止您的主屏幕小部件。然后,它将在自动清理RAM后重新启动您的主屏幕小部件。但是这一次,您的主屏幕小部件将获得与上一个不同的pid,因此无法响应广播。

我认为您应该检查您的应用程序是否存在内存泄漏。您还可以尝试使用alarmManager进行不同的实现。将所有的onUpdate()移动到alarmReceiver中。

看看这个。 使用AlarmManager更新应用程序小部件

或者尝试一个更新服务。


1
谢谢!相反,在AppWidgetProvider中,我使用了服务来代替onReceive方法,一切仍然正常工作。 - Vladimir Milichenko

0
感谢王正宏的帮助。相反,在AppWidgetProvider中的onReceive方法中,我使用了服务。
public class WidgetUpdateService extends Service {

    @Override
    public void onStart(Intent intent, int startId) {
        Context context = getApplicationContext();
        String action = intent.getAction();

        if (CameraHelper.checkCameraFlashLightHadrware(context)
            && (action.equals(XFlashLightAppWidgetProvider.ACTION_WIDGET_RECEIVER)
                    || action.equals(XFlashLightActivity.ACTION_WIDGET_ON) || action
                        .equals(XFlashLightActivity.ACTION_WIDGET_OFF))) {
            RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.appwidget);

            if (action.equals(XFlashLightAppWidgetProvider.ACTION_WIDGET_RECEIVER)) {
                if (!CameraHelper.isTorchFlashMode()) {
                    CameraHelper.initializeCameraFlash();
                    views.setImageViewResource(R.id.widgetLampImage,
                        R.drawable.widget_on);
                } else {
                     CameraHelper.releaseCamera();
                    views.setImageViewResource(R.id.widgetLampImage,
                        R.drawable.widget_off);
                }
            } else if (action.equals(XFlashLightActivity.ACTION_WIDGET_ON)) {
                views.setImageViewResource(R.id.widgetLampImage,
                    R.drawable.widget_on);
            } else if (action.equals(XFlashLightActivity.ACTION_WIDGET_OFF)) {
                views.setImageViewResource(R.id.widgetLampImage,
                    R.drawable.widget_off);
            }

            AppWidgetManager appWidgetManager = AppWidgetManager
                .getInstance(context);
            int[] appWidgetIds = appWidgetManager
                .getAppWidgetIds(new ComponentName(context,
                        XFlashLightAppWidgetProvider.class.getName()));
            for (int i = 0; i < appWidgetIds.length; i++) {
                appWidgetManager.updateAppWidget(appWidgetIds[i], views);
            }
        }
        super.onStart(intent, startId);
    }

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

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接