Отладочный виджет вызывает ANR - PullRequest
5 голосов
/ 07 января 2011

Я пытаюсь отладить AppWidget, но у меня возникла проблема: D Если не установить точку останова, виджет работает без ANR, а команды Log.v выполняются без ошибок. Затем я установил точку останова в верхней части метода:

    public void onReceive(Context context, Intent intent) {
    Log.v(TAG, "onReceive 1"); // BP on this line
    super.onReceive(context, intent);
    String action = intent.getAction();

    // Checks on action and computations ...

    Log.v(TAG, "onReceive 2");
    updateWidget(context);
    Log.v(TAG, "onReceive 3");
}

Точка останова останавливает выполнение, как и ожидалось, но затем процесс умирает. Проблема в том, что точка останова (я полагаю, xD) вызывает ANR, а ActivityManager убивает процесс. Это журнал:

01-07 14:32:38.886: ERROR/ActivityManager(72): ANR in com.salvo.wifiwidget
01-07 14:32:38.886: INFO/Process(72): Sending signal. PID: 475 SIG: 9
......
......
01-07 14:32:38.906: INFO/ActivityManager(72): Process com.salvo.wifiwidget (pid   475) has died.

Это приводит к остановке отладки. Таким образом, вопрос: есть ли способ отладки виджета без использования ANR ?? заранее спасибо за ответы

1 Ответ

2 голосов
/ 17 февраля 2012

Ты прав.Согласно this BroadcastReceiver вашего виджета будет уничтожен системой, если для обработки его метода onReceive потребуется более 10 секунд.

Сверху головы я вижу два решения:

  1. Отделите логику от презентации и отладьте свою логику в Activity, а затем включите ее в виджет.
  2. Используйте «старые добрые» журналы.

ИЛИ вымогу попробовать следующую вещь.Я не уверен, как это будет работать, но, возможно, стоит попробовать этот подход.

Используйте свою собственную деятельность в качестве хоста для RemoteViews виджета.Я сделал что-то вроде этого:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <LinearLayout
            android:id="@+id/widget_view"
            android:layout_width="fill_parent"
            android:layout_height="200dp"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Inflate widget"
        android:onClick="onInflateClick"/>
    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Update widget"
            android:onClick="onUpdateClick"/>
</LinearLayout>

В этом макете LinearLayout с id = widget_view будет воспроизводить хост виджета.Сам код действия выглядит следующим образом:

package com.example;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RemoteViews;

public class MyActivity extends Activity {
    private LinearLayout widgetHolder;
    private View widgetView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        widgetHolder = (LinearLayout) findViewById(R.id.widget_view);
    }

    public void onInflateClick(View v) {
        RemoteViews views = new RemoteViews(getPackageName(), R.layout.widget);
        views.setImageViewResource(R.id.image, R.drawable.img1);
        views.setTextViewText(R.id.text, "Widget created");
        widgetView = views.apply(this, null);
        widgetHolder.addView(widgetView);
    }

    public void onUpdateClick(View v) {
        onUpdateWidget(0);
    }

    public void onUpdateWidget(int widgetId) {
        RemoteViews views = new RemoteViews(getPackageName(), R.layout.widget);
        views.setImageViewResource(R.id.image, R.drawable.img2);
        views.setTextViewText(R.id.text, "Widget updated");

        // Tell the AppWidgetManager to perform an update on the current app widget
        updateWidget(widgetId, views);
    }

    private void updateWidget(int widgetId, RemoteViews views) {
        views.reapply(this, widgetView);
        // appWidgetManager.updateAppWidget(appWidgetId, views);
    }
}

Поместите логику обновления виджета в метод updateWidget (или просто вызовите соответствующий метод onUpdate для BroadcastReceiver виджета с поддельными параметрами), и вы можете отладить его одним нажатием кнопкина вашу деятельность.

Опять же, я никогда не пробовал это на реальном виджете, я просто придумал идею и попытался написать код для него.Используйте его на свой страх и риск:)

Я поставил свой быстрый и грязный проект на github на тот случай, если вы захотите его попробовать.Это и проект Idea, но его легко импортировать в Eclipse.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...