Android Homescreen Widget变得无法响应

时间:2014-03-28 13:41:36

标签: android android-widget

我有一个Android主屏幕小部件我正在处理,一切都很好,除了大约5到6天后,四个按钮恢复到默认状态并变得无法响应。我不明白为什么按钮变得反应迟钝。如果我再次删除并添加小部件,它将再次起作用。如果我等待大约24-48小时,它将再次开始工作一段时间。

我尝试删除android:updatePeriodMillis,以便小部件不会自行更新(它是自包含的,只需要在用户交互时才需要更新)。这也没有用。

这就是我在PendingIntents内设置onUpdate的方式(以this question的答案为模型):

Intent intent1 = new Intent(context, MyWidgetProvider.class);
intent1.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
intent1.setAction(FIRST_INTENT);
intent1.setData(Uri.parse(first_band_intent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, widgetId, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.first_button, pendingIntent1);

然后我在onReceive方法中更新小部件的视图项:

@Override
public void onReceive(Context context, Intent intent) {
    int widgetID = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
    String preferences = PREFS + Integer.toString(widgetID);
    SharedPreferences values = context.getSharedPreferences(preferences, 0);
    int firstBandValue = values.getInt("first_band_value", 1);
    int secondBandValue = values.getInt("second_band_value", 0);
    int multiplierValue = values.getInt("multiplier_value", 2);
    int toleranceValue = values.getInt("tolerance_value", 1);

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);

    if (intent.getAction().equals(FIRST_BAND)) {
        // nextBandColor() will set the proper band based on the next value and return an integer that is BandValue + 1
        firstBandValue = getNextBandColor(context, BandType.FIRST, firstBandValue);

        SharedPreferences.Editor editor = values.edit();
        editor.putInt("first_band_value", firstBandValue);
        editor.commit();
    }
    else if (intent.getAction().equals(SECOND_BAND)) {
        // nextBandColor() will return an integer that is BandValue + 1
        secondBandValue = getNextBandColor(context, BandType.SECOND, secondBandValue);

        SharedPreferences.Editor editor = values.edit();
        editor.putInt("second_band_value", secondBandValue);
        editor.commit();
    }
    else if (intent.getAction().equals(MULTIPLIER)) {
        // nextBandColor() will return an integer that is BandValue + 1
        multiplierValue = getNextBandColor(context, BandType.MULTIPLIER, multiplierValue);

        SharedPreferences.Editor editor = values.edit();
        editor.putInt("multiplier_value", multiplierValue);
        editor.commit();
    }
    else if (intent.getAction().equals(TOLERANCE)) {
        // nextBandColor() will return an integer that is BandValue + 1
        toleranceValue = getNextBandColor(context, BandType.TOLERANCE, toleranceValue);

        SharedPreferences.Editor editor = values.edit();
        editor.putInt("tolerance_value", toleranceValue);
        editor.commit();
    }
    else {
        super.onReceive(context, intent);
    }

    //Update the view items based on the new integer values; calls updateAppWidget()
    updateBands(context, widgetID, firstBandValue, secondBandValue, multiplierValue, toleranceValue);

    // Concatenate the integer value of the first band value with the integer value of the second band color
    String value = Integer.toString(firstBandValue) + Integer.toString(secondBandValue);

    // Turn the concatenation of the two integers into a double value
    baseValue = Double.parseDouble(value);

    multiplyBaseValue(multiplierValue);

    String units = getUnitsAndAdjustBaseValue();
    String tolerance = getTolerance(toleranceValue);

    DecimalFormat df = new DecimalFormat("#.#");
    resistance = df.format(baseValue) + units + tolerance;

    remoteViews.setTextViewText(R.id.resistance_value, resistance);


    AppWidgetManager manager = AppWidgetManager.getInstance(context);
    manager.updateAppWidget(widgetID, remoteViews);
}

此小部件设计为独立的,没有任何活动或服务。

更新1 :如果我在return之后向onReceive的其他人添加super.onReceive()语句,则会恢复原始布局,但没有反应迟钝。

更新2:我看了here onReceive()方法必须在5秒内完成处理。可能问题是我的onReceive()没有在规定的时间内完成,从而导致小部件冻结?

此问题也与设备无关。它发生在Galaxy Nexus,Nexus 7 2012和Galaxy S4上。

什么可能导致这种无反应的问题?

1 个答案:

答案 0 :(得分:0)

首先测试你的onReceive()代码以查看错误是在那里还是其他地方 - 最好在查找“随机”或“怪异”错误时测试假设。

所以要测试它,绝对简化它,使它100%无足轻重。删除所有有趣的代码,只需将其更改为简单的文本。一些不可能有错误的东西。

@Override
public void onReceive(Context context, Intent intent) {
    int widgetID = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
    remoteViews.setTextViewText(R.id.resistance_value, "1.2 ohms");

    AppWidgetManager manager = AppWidgetManager.getInstance(context);
    manager.updateAppWidget(widgetID, remoteViews);
}

如果这仍然存在,那么您就知道该错误不在您的onReceive()代码中。所以你可以去其他地方看看。

如果这样可以解决问题,那么您就知道onReceive()的部分内容已经破坏了小部件。

逐位添加代码,添加大量日志记录(Log.d())。

您可能希望查看SharedPreferences访问权限,因为这是文件访问权限。另请查看此帖子,并考虑使用SharedPreferences.Editor.apply()

通常采用这种方法,您将能够找到错误,或者至少将其缩小到非常具体的内容,这样可以更容易地获得帮助。