Android Wear setContentAction starts and soon stops Activity causing: Performing pause of activity that is not resumed

痴心易碎 提交于 2019-12-11 20:35:01

问题


I am doing Android Wear project. Notification is displayed to user with contentAction, so user can tap it. After taping it SomeActivity is displayed with DelayedConfirmationView giving user time to cancel upcoming API request. When DelayedConfirmationView finish API call is made. After API call succeeds ConfirmationActivity is shown. When ConfirmationActivity returns we finish() SomeActivity and cancel the notification.

The problem I face is that after SomeActivity starts it is mysteriously stopped without a reason. The log together with the crash looks like follows:

05-20 08:07:49.865 D/My App Wear( 7122): SomeActivity: onCreate
05-20 08:07:49.923 D/My App Wear( 7122): SomeActivity: onStart
05-20 08:07:49.923 D/My App Wear( 7122): SomeActivity: onResume
05-20 08:07:49.991 D/My App( 7122): Google API client connected
05-20 08:07:50.489 D/ViewRootImpl( 7122): changeCanvasOpacity: opaque=true
05-20 08:07:50.492 D/My App Wear( 7122): SomeActivity: onStop
05-20 08:07:53.482 E/My App( 7122): No connection to wearable available!
05-20 08:08:01.689 W/art     ( 7122): Suspending all threads took: 34.878ms
05-20 08:08:01.779 E/ActivityThread( 7122): Performing pause of activity that is not resumed: {SomeActivity}
05-20 08:08:01.779 E/ActivityThread( 7122): java.lang.RuntimeException: Performing pause of activity that is not resumed: {SomeActivity}
05-20 08:08:01.779 E/ActivityThread( 7122):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3196)
05-20 08:08:01.779 E/ActivityThread( 7122):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3184)
05-20 08:08:01.779 E/ActivityThread( 7122):     at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3159)
05-20 08:08:01.779 E/ActivityThread( 7122):     at android.app.ActivityThread.access$1000(ActivityThread.java:144)
05-20 08:08:01.779 E/ActivityThread( 7122):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1289)
05-20 08:08:01.779 E/ActivityThread( 7122):     at android.os.Handler.dispatchMessage(Handler.java:102)
05-20 08:08:01.779 E/ActivityThread( 7122):     at android.os.Looper.loop(Looper.java:135)
05-20 08:08:01.779 E/ActivityThread( 7122):     at android.app.ActivityThread.main(ActivityThread.java:5221)
05-20 08:08:01.779 E/ActivityThread( 7122):     at java.lang.reflect.Method.invoke(Native Method)
05-20 08:08:01.779 E/ActivityThread( 7122):     at java.lang.reflect.Method.invoke(Method.java:372)
05-20 08:08:01.779 E/ActivityThread( 7122):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
05-20 08:08:01.779 E/ActivityThread( 7122):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
05-20 08:08:01.779 D/My App Wear( 7122): SomeActivity: onPause
05-20 08:08:01.961 E/ActivityThread( 7122): Performing stop of activity that is not resumed: {SomeActivity}
05-20 08:08:01.961 E/ActivityThread( 7122): java.lang.RuntimeException: Performing stop of activity that is not resumed: {SomeActivity}
05-20 08:08:01.961 E/ActivityThread( 7122):     at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3309)
05-20 08:08:01.961 E/ActivityThread( 7122):     at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3390)
05-20 08:08:01.961 E/ActivityThread( 7122):     at android.app.ActivityThread.access$1100(ActivityThread.java:144)
05-20 08:08:01.961 E/ActivityThread( 7122):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
05-20 08:08:01.961 E/ActivityThread( 7122):     at android.os.Handler.dispatchMessage(Handler.java:102)
05-20 08:08:01.961 E/ActivityThread( 7122):     at android.os.Looper.loop(Looper.java:135)
05-20 08:08:01.961 E/ActivityThread( 7122):     at android.app.ActivityThread.main(ActivityThread.java:5221)
05-20 08:08:01.961 E/ActivityThread( 7122):     at java.lang.reflect.Method.invoke(Native Method)
05-20 08:08:01.961 E/ActivityThread( 7122):     at java.lang.reflect.Method.invoke(Method.java:372)
05-20 08:08:01.961 E/ActivityThread( 7122):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
05-20 08:08:01.961 E/ActivityThread( 7122):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Creating notification snipped:

private NotificationCompat.Builder createNotification()
    {    
        NotificationCompat.Action someAction = createSomeAction();

        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this.context)
                        .setSmallIcon(R.drawable.logo)
                        .setLargeIcon(BitmapFactory.decodeResource(
                                this.context.getResources(), R.drawable.logo))
                        .setContentTitle(title)
                        .setContentText(subtitle)
                        .addAction(saveAction)

        NotificationCompat.WearableExtender wearableExtender = new NotificationCompat.WearableExtender()
                .setBackground(BitmapFactory.decodeResource(this.context.getResources(), getRandomBackground()))
                .setContentAction(0)
                .setCustomContentHeight(Utils.dpToPx(100, this.context));

        notificationBuilder.extend(wearableExtender);

        return notificationBuilder;
    }

private NotificationCompat.Action createSaveAction()
    {
        Intent saveIntent = new Intent(this.context, SomeActivity.class);
        PendingIntent savePendingIntent =
                PendingIntent.getActivity(this.context, 3, saveIntent, PendingIntent.FLAG_CANCEL_CURRENT);

        NotificationCompat.Action saveAction =
                new NotificationCompat.Action.Builder(R.drawable.save,
                        this.context.getString(R.string.save), savePendingIntent)
                        .build();

        return saveAction;
    }

SomeActivity:

    public class SomeActivity implements
            DelayedConfirmationView.DelayedConfirmationListener
    {
        private static final int SOME_NOTIFICATION_REQUEST_CODE = 99;
        private DelayedConfirmationView delayedConfirmationView;
        private TextView description;
        private ProgressView progressView;
        private TextView saveLabel;
        protected GoogleApiClient googleApiClient;

        @Override
        public void onCreate(Bundle bundle)
        {
            super.onCreate(bundle);
            setContentView(R.layout.activity_some);
            this.description = (TextView) findViewById(R.id.activity_some_description);
            this.delayedConfirmationView = (DelayedConfirmationView) findViewById(R.id.activity_some_delayed_confirmation);
            this.delayedConfirmationView.setTotalTimeMs(Constants.DELAYED_CONFIRMATION_ANIMATION_TIME_IN_SEC * Constants.MILIS_PER_SECOND);
            this.progressView = (ProgressView)findViewById(R.id.activity_some_progress_view);
            this.someLabel = (TextView)findViewById(R.id.activity_some_label);

            CardScrollView cardScrollView = (CardScrollView) findViewById(R.id.activity_some_card_scroll_view);
            cardScrollView.setCardGravity(Gravity.BOTTOM);

            new GetDataFromDBAsyncTask().execute();
            this.googleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(Wearable.API)
                .build();
        }

        @Override
        protected void onStart()
        {
           super.onStart();
           this.googleApiClient.connect();
        }

        @Override
        protected void onResume()
        {
            super.onResume();
            Handler handler = new Handler();
            handler.postDelayed(new Runnable()
            {
                @Override
                public void run()
                {
                    onStartTimer();
                }
            }, 500);
        }

        @Override
        protected void onPause()
        {
            super.onPause();
            this.delayedConfirmationView.setListener(null);
        }

        @Override
        protected void onStop()
        {
            super.onStop();
            if (null != this.googleApiClient && this.googleApiClient.isConnected())
            {
                Wearable.MessageApi.removeListener(this.googleApiClient, this);
                this.googleApiClient.disconnect();
            }
        }

        @Override
        public void onConnected(Bundle bundle)
        {
            Log.d(Constants.LOG_TAG, "Google API client connected");
            Wearable.MessageApi.addListener(this.googleApiClient, this);
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data)
        {
            super.onActivityResult(requestCode, resultCode, data);

            if (requestCode == SOME_NOTIFICATION_REQUEST_CODE)
            {
                WearableNotificationCenter.getInstance(SomeActivity.this).cancelNotification();
                finish();
            }
        }

        public void onStartTimer()
        {
            this.delayedConfirmationView.setListener(this);
            this.delayedConfirmationView.start();
        }

        @Override
        public void onTimerSelected(View view)
        {
            view.setPressed(true);
            // Prevent onTimerFinished from being heard.
            this.delayedConfirmationView.setListener(null);
            finish();
        }

        @Override
        public void onTimerFinished(View v)
        {
            this.delayedConfirmationView.setEnabled(false);
            this.delayedConfirmationView.setVisibility(View.INVISIBLE);
            this.progressView.setVisibility(View.VISIBLE);
            this.saveLabel.setText(R.string.saving);

            sendApiRequest();
        }

        private void showSaveConfirmation()
        {
            Intent intent = new Intent(this, ConfirmationActivity.class);
            intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE,
                    ConfirmationActivity.SUCCESS_ANIMATION);
            intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE,
                    getString(R.string.done));
            startActivityForResult(intent, SOME_NOTIFICATION_REQUEST_CODE);
        }

        private void sendApiRequest()
        {
            some code
        }

        @Override
        public void handleApiResponse(MessageEvent messageEvent)
        {

            showSaveConfirmation();
        }
    }

I was trying many things to make it working but nothing really worked. Any ideas? Can DelayedConfirmationView cause such a misbehaviour? I saw examples in the Net and they start it even in onCreate, so it cannot be it.

What bothers me most is that there is onStop called before onPause. This is very strange. In the SomeActivity you can see that in onStop I disconnect from the GoogleApiClient but Activity is still alive, because logs shows that it tries to call API 3 seconds after activity was started (3 seconds take DelayedConfirmationView to finish). The problem is that this activity is not displayed to the user since mysterious onStop was called.


回答1:


Looks like latest OS update solved the issue.



来源:https://stackoverflow.com/questions/30343118/android-wear-setcontentaction-starts-and-soon-stops-activity-causing-performing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!