首先,我知道不应该在Android上杀死/重启应用程序.在我的用例中,我想在服务器向客户端发送特定信息的特定情况下出厂重置我的应用程序.
用户只能使用应用程序的一个实例登录服务器(即不允许多个设备).如果另一个实例获得"登录"锁定,那么该用户的所有其他实例都必须删除其数据(工厂重置),以保持一致性.
可以强制获取锁定,因为用户可能会删除应用程序并重新安装它,这将导致不同的实例ID,并且用户将无法再释放锁定.因此可以强行锁定.
由于这种力的可能性,我们需要始终检查具有锁定的具体实例.这是(几乎)对服务器的每个请求完成的.服务器可能会发送"error-lock-id".如果检测到,则客户端应用程序必须删除所有内容.
那是用例.不执行问题:
我有一个ActivityA启动Login ActivityL或应用程序的主ActivityB,具体取决于sharedPrefs字段.在启动L或B后,它自行关闭,只有L或B运行.因此,在用户已登录的情况下,B现在正在运行.
B开始C. C调用startService为IntentServiceD.导致这个堆栈:
(A)> B> C> D.
从D的onHandleIntent方法,事件被发送到ResultReceiver R.
R现在通过向用户提供一个对话框来处理该事件,在该对话框中他可以选择出厂重置应用程序(删除数据库,sharedPrefs等)
出厂重置后,我想重新启动应用程序(关闭所有活动),然后再次启动A,然后启动登录ActivityL并自行完成:
(A)> L.
Dialog的onClick方法如下所示:
@Override
public void onClick(DialogInterface dialog, int which) {
// Will call onCancelListener
MyApplication.factoryReset(); // (Deletes the database, clears sharedPrefs, etc.)
Intent i = new Intent(MyApp.getContext(), A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MyApp.getContext().startActivity(i);
}
Run Code Online (Sandbox Code Playgroud)
这就是MyApp班级:
public class MyApp extends Application {
private static Context context;
@Override
public void onCreate() { …Run Code Online (Sandbox Code Playgroud) 该属性究竟taskAffinity用于什么?我已经阅读了文档但我无法理解.
任何人都可以解释外行人的任务亲和力吗?
我正在尝试在我的应用程序中创建一个"注销"功能.基本上,通过注销,应清除应用程序数据.我想要做的是在注销后,应用程序应该重新启动,以便可以再次输入凭据等.我遇到的问题是,当用户单击"注销"时,应用程序已经运行了3-4个活动,我不知道如何退回它们.我如何(模拟?)重新启动应用程序?
在Android应用程序中,如果我们没有得到正确的例外,我们通常会收到"强制关闭"错误.
如果强行关闭,如何自动重启我的应用程序?
是否有任何特定的权限用于此?
我在logcat的应用程序的第一行收到此警告,但我不知道它指的是什么以及应该如何修复它。Google对此没有提供太多信息(实际上根本没有提供)。请指教。这可能是什么样的标志?有没有一种方法可以找出指定位可能引用的内容(或者也许在较旧的Android版本上已引用过)?Android 9或更早版本的日志中没有这样的行。
在过去的几周里,我遇到了我的崩溃记者:
Fatal Exception: java.lang.RuntimeException: Unable to start service com.####.MyService@ef705d8 with Intent { act=HIDE cmp=com.####/.MyService (has extras) }: java.lang.RuntimeException: android.os.DeadSystemException
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3344)
at android.app.ActivityThread.-wrap21(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1583)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6121)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
Run Code Online (Sandbox Code Playgroud)
此崩溃存在于:
所有三星设备7.0
7.1.2上的所有Nexus设备
注意:
这不是因为最近我们的应用程序更新,只是这些手机上的操作系统更新.
这是一次非常频繁的崩溃(到目前为止我们最大的崩溃).
我们的用户不会报告崩溃事件(这种崩溃实际上对用户是否可见?)
我们无法在我们这边重现它
正如您可以看到堆栈跟踪,受影响的代码仅限系统.我不能在我这边做,试图抓住并处理这个问题.
我检查了线程Android DeadSystemException,但这对我没什么帮助.
我知道的DeadSystemException是:
核心Android系统已经死亡并且正在重启运行时.所有正在运行的应用程序都会被迅速杀死
除了说"那个系统,我们什么都做不了"之外,我们能做些什么吗?
我想通过待处理意图重新启动我的应用程序。下面的代码不起作用。
val intent = Intent(this, Activity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
}
val pendingIntentId = 1
val pendingIntent = PendingIntent.getActivity(this, pendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT)
val mgr = getSystemService(Context.ALARM_SERVICE) as AlarmManager
val timeToStart = System.currentTimeMillis() + 1000L
mgr.set(AlarmManager.RTC, timeToStart, pendingIntent)
exitProcess(0)
Run Code Online (Sandbox Code Playgroud)
目标版本是 31,因此更新了未决意图,但PendingIntent.FLAG_MUTABLE仍然不起作用。我搜索了许多与此相关的链接,但没有运气。
2022 年 11 月,当目标版本为 31 且最低 sdk 版本为 29 时,上述待处理意图代码不会重新启动应用程序。
除了重新启动活动之外,还有为什么上述未决意图不起作用的任何线索或任何其他建议吗?我不想使用重新启动startActivity(intent)
这是对这个问题的后续问题:
我试图从像这样的片段重新启动我的应用程序:
Toast.makeText(getActivity(), "Restarting app", Toast.LENGTH_SHORT).show();
Intent i = getActivity().getBaseContext().getPackageManager()
.getLaunchIntentForPackage(getActivity().getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
getActivity().finish();
Run Code Online (Sandbox Code Playgroud)
代码什么也没做.这finish()是唯一有用的原因.如果我删除finish(),没有任何反应.这是为什么?
我需要以编程方式重新启动应用程序.我的启动器活动称为" 登录 ",登录后,主要活动称为" 主要 ".在主要活动中,我想重新启动应用程序.所以我有以下内容:
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Run Code Online (Sandbox Code Playgroud)
这将显示"登录"活动,但是当我按下时,我将返回上一个活动.
有没有更好的方法来真正重启应用程序?