调试窗口小部件会导致ANR

时间:2011-01-07 13:51:37

标签: android eclipse android-widget

我正在尝试调试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 个答案:

答案 0 :(得分:2)

你是对的。根据{{​​3}},如果处理onReceive方法花费的时间超过10秒,系统将杀死Widget的BroadcastReceiver。

从头顶我可以看到两个解决方案:

  1. 在Activity中将逻辑与演示和调试逻辑分开,然后将其合并到widget中。
  2. 诉诸“老好”伐木。
  3. 或者您可以尝试以下内容。我不确定它是如何工作的,但也许值得尝试这种方法。

    使用您自己的活动作为窗口小部件RemoteView的主机。我做过这样的事情:

    <?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>
    

    在此布局中,具有id = widget_view的LinearLayout将播放小部件主机。活动代码本身如下所示:

    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方法(或者只使用假参数调用小部件的BroadcastReceiver的正确onUpdate方法),然后只需单击活动上的按钮就可以调试它。

    同样,我从来没有尝试过真正的小部件,我只想出了想法并试图为它编写代码。使用它自担风险:)

    我将快速而又脏的项目放到this以防您想要尝试。这是和Idea项目,但它应该很容易导入Eclipse。