问题
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