【问题标题】:Debugger disconnecting in Android Studio when debugging a home screen widget调试主屏幕小部件时调试器在 Android Studio 中断开连接
【发布时间】:2017-05-16 10:34:27
【问题描述】:

我正在尝试调试我制作的 Android 主屏幕小部件应用程序。 当按下小部件上的按钮时,调试器将启动,然后它只是与 VM 断开连接。没有给出任何理由。我正在使用 Windows 10。

日志是这样说的:

D/Atlas: Validating map... D/libEGL: loaded
/system/lib/egl/libEGL_emulation.so D/libEGL: loaded
/system/lib/egl/libGLESv1_CM_emulation.so D/libEGL: loaded
/system/lib/egl/libGLESv2_emulation.so

D/         ] HostConnection::get() New Host Connection established 0xef0394f0, tid 3709 
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Enabling debug mode 0 W/EGL_emulation: eglSurfaceAttrib not implemented 
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xef1485e0, error=EGL_SUCCESS
D/roboguice.RoboGuice: Using annotation database(s).
D/roboguice.RoboGuice: Using annotation database(s) : [, roboguice]
D/roboguice.RoboGuice: Time spent loading annotation databases : 21
W/art: Verification of com.gdbd.geedeebeedee.model.GdbdWidgetRecord 
    com.gdbd.geedeebeedee.model.GdbdWidgetRecordsRealmImpl.create(java.util.Date) took 127.878ms
W/art: Verification of com.gdbd.geedeebeedee.model.GdbdWidgetRecord
    com.gdbd.geedeebeedee.model.GdbdWidgetRecordsRealmImpl.getTodaysRecord() took 111.586ms
D/GdbdWidgetBase: Received intent: android.appwidget.action.APPWIDGET_ENABLED
D/GdbdWidgetBase: Updating widget index: 0 with id: 23
D/GdbdWidgetBase: Received intent: android.appwidget.action.APPWIDGET_UPDATE
D/GdbdWidgetBase: Received intent: android.appwidget.action.APPWIDGET_UPDATE_OPTIONS
D/GdbdWidgetBase: Received intent: change_day_staus
I/art: Thread[5,tid=3470,WaitingInMainSignalCatcherLoop,Thread*=0xf3c30c00,
    peer=0x22c0a0a0,"Signal Catcher"]: reacting to signal 3
I/art: Wrote stack traces to '/data/anr/traces.txt' 
Disconnected from the target VM, address: 'localhost:8619', transport: 'socket'

我也提取了 traces.txt,但没有发现任何明显的错误信息。也许我不知道要寻找什么。首次将小部件放置在屏幕上时,调试器不会断开连接。官方模拟器和 GenyMotion 都会发生这种情况。模拟器是 Google Nexus 5 5.1.0 API 22。

这些是 Gradle 构建设置:

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"
    defaultConfig {
        applicationId "com.gdbd.geedeebeedee"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    } }

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

    compile group: 'com.google.code.gson', name: 'gson', version: '2.3.1'
    compile 'com.android.support:appcompat-v7:25.0.0'

    compile 'org.roboguice:roboguice:3.+'
    provided 'org.roboguice:roboblender:3.+'

    testCompile 'junit:junit:4.12' }

有谁知道发生了什么以及为什么我无法调试?谢谢。

编辑 1:

显然这个进程死掉了。

D/OpenGLRenderer: Enabling debug mode 0 
W/EGL_emulation: eglSurfaceAttrib not implemented 
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xf3ff6900, error=EGL_SUCCESS
D/roboguice.RoboGuice: Using annotation database(s).
D/roboguice.RoboGuice: Using annotation database(s) : [, roboguice]
D/roboguice.RoboGuice: Time spent loading annotation databases : 19
80:   80 D/         ] Socket deconnection 
D/GdbdWidgetBase: Received intent: change_day_staus
80:   80 D/         ] Socket deconnection
80:   80 D/         ] Socket deconnection
80:   80 D/         ] Socket deconnection
80:   80 D/         ] Socket deconnection 
I/art: Thread[5,tid=13474,WaitingInMainSignalCatcherLoop,Thread*=0xf3c30c00,
    peer=0x12c0a0a0,"Signal Catcher"]: reacting to signal 3
I/art: Wrote stack traces to '/data/anr/traces.txt'

编辑 2 添加 Android 清单文件

`

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <meta-data
        android:name="roboguice.modules"
        android:value="com.gdbd.geedeebeedee.model.ModelModule" />


    <activity
        android:name=".activity.StatsActivity"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <receiver android:name=".widget.GdbdWidgetBase" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <intent-filter>
            <action android:name="change_day_staus" />
        </intent-filter>


        <meta-data android:name="android.appwidget.provider"
            android:resource="@xml/gdbd_widget_info" />

    </receiver>

</application>

`

编辑 3 traces.txt https://ufile.io/c41eb

编辑 4 GdbdWidgetBase

@Inject
    GdbdWidgetRecords gdbdWidgetRecords;

    public void onHandleUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // Perform this loop procedure for each App Widget that belongs to this provider
        for (int widgetIndex = 0; widgetIndex < appWidgetIds.length; widgetIndex++) {
            int widgetId = appWidgetIds[widgetIndex];
            Log.d(TAG, "Updating widget index: " + widgetIndex + " with id: " + widgetId);

            GdbdWidgetRecord todaysRecord = gdbdWidgetRecords.getTodaysRecord();

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

            if(todaysRecord.getCurrentStatus() == DayStatus.GOODDAY)
                views.setImageViewResource(R.id.btnClicker, R.drawable.ic_gd);
            else if(todaysRecord.getCurrentStatus() == DayStatus.BADDAY)
                views.setImageViewResource(R.id.btnClicker, R.drawable.ic_bd);
            else if(todaysRecord.getCurrentStatus() == DayStatus.NOTSET)
                views.setImageViewResource(R.id.btnClicker, R.drawable.ic_undecided);


            Intent intent = new Intent(context, GdbdWidgetBase.class);
            intent.setAction(CHANGE_DAY_STATUS);
            intent.putExtra(WIDGET_ID_EXTRA, widgetId);
            PendingIntent changeStatusIntent = PendingIntent.getBroadcast(context, widgetId, intent,
                    PendingIntent.FLAG_CANCEL_CURRENT);
            views.setOnClickPendingIntent(R.id.btnClicker, changeStatusIntent);

            scheduleUpdateAtMidnight(context, widgetId);

            appWidgetManager.updateAppWidget(widgetId, views);
        }
    }

    @Override
    public void onHandleReceived(Context context, Intent intent) {
        Log.d(TAG, "Received intent: " + intent.getAction());
        //Log.d(TAG,"getDebugUnregister: " + (getDebugUnregister()?"true":"false"));

        if (CHANGE_DAY_STATUS.equals(intent.getAction())) {

            int appWidgetId = intent.getIntExtra(WIDGET_ID_EXTRA, -1);
            if (appWidgetId >= 0) {
                GdbdWidgetRecord todaysRecord = gdbdWidgetRecords.getTodaysRecord();
                Log.d(TAG, "today record: " + todaysRecord.toString());
                DayStatus newDayStatus = DayStatus.NOTSET;

                if(todaysRecord.getCurrentStatus() == DayStatus.NOTSET)
                    newDayStatus = DayStatus.GOODDAY;
                else if(todaysRecord.getCurrentStatus() == DayStatus.GOODDAY)
                    newDayStatus = DayStatus.BADDAY;
                else if(todaysRecord.getCurrentStatus() == DayStatus.GOODDAY)
                    newDayStatus = DayStatus.NOTSET;

                Log.d(TAG, "newDayStatus: " + newDayStatus);

                gdbdWidgetRecords.changeTodaysStatus(newDayStatus);
                onHandleUpdate(context, AppWidgetManager.getInstance(context), new int[]{appWidgetId});
            }
        }
    }

    private void scheduleUpdateAtMidnight(Context context, int widgetId) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.SECOND, 1);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.add(Calendar.DAY_OF_YEAR, 1);

        Intent updateAtMidnightIntent = new Intent(context, GdbdWidgetBase.class);
        updateAtMidnightIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
        updateAtMidnightIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[]{widgetId});

        PendingIntent broadcastIntent = PendingIntent.getBroadcast(context, widgetId + 1,
                updateAtMidnightIntent, PendingIntent.FLAG_CANCEL_CURRENT);

        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), broadcastIntent);
        } else {
            alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), broadcastIntent);
        }
    }

编辑 5 断点总是在我的 AppWidget 的 onReceive() 方法中。 对于 android.appwidget.action.APPWIDGET_ENABLED 等其他意图,在调试器停止之前需要更多时间,但我的应用仍然死机

01-09 22:28:20.861 3881-3881/com.gdbd.geedeebeedee D/GdbdWidget: Received intent: android.appwidget.action.APPWIDGET_ENABLED
01-09 22:29:20.854 3881-3886/com.gdbd.geedeebeedee I/art: Thread[2,tid=3886,WaitingInMainSignalCatcherLoop,Thread*=0x7fbcebe06000,peer=0x2ac070a0,"Signal Catcher"]: reacting to signal 3
01-09 22:29:21.013 3881-3886/com.gdbd.geedeebeedee I/art: Wrote stack traces to '/data/anr/traces.txt'

而对于我自己在小部件中按下按钮时发送的意图需要 10 秒。

01-09 22:34:25.353 4314-4314/com.gdbd.geedeebeedee D/GdbdWidget: Received intent: change_day_staus
01-09 22:34:35.362 4314-4319/com.gdbd.geedeebeedee I/art: Thread[2,tid=4319,WaitingInMainSignalCatcherLoop,Thread*=0x7fbcebe06000,peer=0x2ac070a0,"Signal Catcher"]: reacting to signal 3
01-09 22:34:35.549 4314-4319/com.gdbd.geedeebeedee I/art: Wrote stack traces to '/data/anr/traces.txt'

【问题讨论】:

  • 请提供您的 AndroidManifest.xml,您的 AppWidget 是否与应用在同一进程中运行?
  • 我添加了 AndroidManifest。如何检查我的 AppWidget 是否与应用程序在同一进程中运行?我是 Android 开发的新手。谢谢
  • 它会在设备上引发任何警告/对话框吗?你能找回这里提到的traces.txt吗:I/art: Wrote stack traces to '/data/anr/traces.txt'
  • 我没有在设备上看到任何警告对话框。我在这里上传了 traces.txt ufile.io/c41eb
  • 能否也提供.widget.GdbdWidgetBase的代码?

标签: android debugging android-studio android-sdk-tools


【解决方案1】:

我转到模拟设备的设置 -> 开发人员选项并启用“显示所有 ANR”,现在出现警告“您的应用程序没有响应”,我可以点击“等待”,它似乎工作。

【讨论】:

    【解决方案2】:

    这不是停止分离的解决方案。但是您可以在之后直接重新附加调试器。您可以使用工具栏中的按钮将调试器附加到正在运行的进程:

    我知道这并不理想,但也许已经足够为你继续调试了。

    【讨论】:

    • 我的应用程序进程被终止,我无法再附加到它,我必须重新启动它。
    • 与@Para 发生同样的事情
    【解决方案3】:

    您是否尝试过在 Android Studio 上禁用即时运行。可能是调试时发生冲突。

    【讨论】:

    • 我试过了,但没有用。不过我确实注意到了一些东西。在我的自定义意图 change_day_status 上,调试器在 10 秒内崩溃,在 android.appwidget.action.APPWIDGET_ENABLED 等其他事件上则需要一分钟。
    • 你能告诉我你在哪里使用你的调试点吗?我认为您正在使用在 UI 线程上需要完成大量工作的行上的调试点可能是因为哪个调试器正在分离。
    • 我有一个类 GdbdWidget 扩展了 AppWidgetProvider,我在这个类的 onReceive() 方法中设置了断点
    【解决方案4】:

    使用 Android studio 的这个插件。 ADB WIFI

    连接两台设备 1) PC/笔记本电脑 2) 同一网络上的移动设备并执行此操作 工具 -> Android -> ADB WIFI -> ADB USB 转 WIFI。

    谢谢

    【讨论】:

    • 出现一条消息“无法连接到无线或获取有效的 IP 地址”
    • 两个设备(PC/笔记本电脑和移动设备)必须在同一个 wifi 网络上,它应该可以工作。首先,用USB连接,然后在连接后运行该程序,您可以断开电缆。
    【解决方案5】:

    我有类似的问题。原来断点在必须执行一些 UI 任务(意图调用其他活动)的行上。只需将断点移动到不涉及 UI 处理的其他地方。我这样解决了我的问题。

    【讨论】:

      【解决方案6】:

      也许这对你有帮助。请检查以下建议后

      您选择您的设备,然后在右侧选择您的软件包名称,您可以在 regex 旁边看到从下拉列表中选择仅显示选定的应用程序

      【讨论】:

      • 我按照你的建议做了。请参阅上面的编辑。显然这个过程死了。但我不知道为什么。
      猜你喜欢
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      相关资源
      最近更新 更多