为了账号安全,请及时绑定邮箱和手机立即绑定

请问如何以编程方式“重新启动”Android应用程序?

/ 猿问

请问如何以编程方式“重新启动”Android应用程序?

慕莱坞森 2019-11-15 11:10:28

如何以编程方式“重新启动”Android应用程序?

首先,我知道不应该真的在Android上杀死/重新启动一个应用程序。在我的用例中,我想在服务器向客户端发送特定信息的特定情况下重新设置我的应用程序。

用户只能使用应用程序的一个实例登录到服务器上(即不允许使用多个设备)。如果另一个实例获得“登录”-锁,则该用户的所有其他实例都必须删除他们的数据(工厂重置),以保持一致性。

可以强行获得锁,因为用户可能会删除应用程序并重新安装它,这将导致一个不同的实例-id,用户将无法再释放锁。因此,强行获取锁是可能的。

因为这种力-可能性,我们需要始终检查一个具体的实例,它有锁。这是在(几乎)对服务器的每个请求上完成的。服务器可能会发送“错误的锁id”。如果检测到这一点,则客户端应用程序必须删除所有内容。


那是用例。

我有一个Activity启动登录的AActivity或应用程序的主Activityb取决于SharedPrefs值。在启动L或B之后,它会关闭自己,因此只有L或B在运行。因此,在用户已经登录的情况下,B现在正在运行。

B启动C.C呼叫startServiceIntentServiceD.导致这一堆的结果:

(A)>B>C>D

从D的onHandleIntent方法中,将一个事件发送到结果收发器R.

r现在通过向用户提供一个对话框来处理该事件,用户可以在其中选择重新设置应用程序(删除数据库、sharedPrefs等)。

在工厂重置之后,我想重新启动应用程序(关闭所有活动),然后再次启动A,然后启动登录Activity并完成自己:

(A)>L

对话框的onClick-方法如下所示:

@Overridepublic 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);}

这就是MyApp班级:

public class MyApp extends Application {
    private static Context context;

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }

    public static Context getContext() {
        return context;
    }

    public static void factoryReset() {
        // ...
    }}

问题是如果我使用FLAG_ACTIVITY_NEW_TASK活动B和C仍在运行。如果我在登录时按后退按钮Activity我看到C了,但我想回到主屏幕上。

如果我不设置FLAG_ACTIVITY_NEW_TASK我知道错误:

07-07 12:27:12.272: ERROR/AndroidRuntime(9512): android.util.AndroidRuntimeException:
 Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

我不能用这些活动Context,因为ServiceIntent控件启动的后台任务也可以调用d。AlarmManager.

那么,我如何解决这个问题,使活动堆栈变成(A)>L?


查看完整描述

3 回答

?
慕哥9229398

你只需打电话:

public static void triggerRebirth(Context context, Intent nextIntent) {
    Intent intent = new Intent(context, YourClass.class);
    intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
    intent.putExtra(KEY_RESTART_INTENT, nextIntent);
    context.startActivity(intent);
    if (context instanceof Activity) {
      ((Activity) context).finish();
    }

    Runtime.getRuntime().exit(0);}

中使用的凤凰进程图书馆


作为替代办法:

以下是@OlegKoshkin答案的一个改进版本。

如果您确实希望重新启动您的活动,包括终止当前进程,请尝试以下代码。将它放在HelperClass中或需要它的地方。

public static void doRestart(Context c) {
        try {
            //check if the context is given
            if (c != null) {
                //fetch the packagemanager so we can get the default launch activity 
                // (you can replace this intent with any other activity if you want
                PackageManager pm = c.getPackageManager();
                //check if we got the PackageManager
                if (pm != null) {
                    //create the intent with the default start activity for your application
                    Intent mStartActivity = pm.getLaunchIntentForPackage(
                            c.getPackageName()
                    );
                    if (mStartActivity != null) {
                        mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        //create a pending intent so the application is restarted after System.exit(0) was called. 
                        // We use an AlarmManager to call this intent in 100ms
                        int mPendingIntentId = 223344;
                        PendingIntent mPendingIntent = PendingIntent
                                .getActivity(c, mPendingIntentId, mStartActivity,
                                        PendingIntent.FLAG_CANCEL_CURRENT);
                        AlarmManager mgr = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
                        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
                        //kill the application
                        System.exit(0);
                    } else {
                        Log.e(TAG, "Was not able to restart application, mStartActivity null");
                    }
                } else {
                    Log.e(TAG, "Was not able to restart application, PM null");
                }
            } else {
                Log.e(TAG, "Was not able to restart application, Context null");
            }
        } catch (Exception ex) {
            Log.e(TAG, "Was not able to restart application");
        }
    }

这还将重新初始化JNI类和所有静态实例。



查看完整回答
反对 回复 2019-11-16
?
波斯汪

IntentCompat.makeRestart ActivityTask

做这件事的新方法是IntentCompat.makeRestart ActivityTask

创建一个可用于重新启动处于基本状态的应用程序任务的意图。这类似于makeMainActivity(ComponentName),但也设置了标志Intent.FLAG_Activity_New_Task和标志_Activity_CLEAR_TACT。

PackageManager packageManager = context.getPackageManager();Intent intent = packageManager.getLaunchIntentForPackage(context.getPackageName());
ComponentName componentName = intent.getComponent();Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName);
context.startActivity(mainIntent);System.exit(0);



查看完整回答
反对 回复 2019-11-16
?
元芳怎么了

你可以用PendingIntent设置以后启动开始活动,然后关闭应用程序

Intent mStartActivity = new Intent(context, StartActivity.class);

int mPendingIntentId = 123456;

PendingIntent mPendingIntent = PendingIntent.getActivity(context, mPendingIntentId,    mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);

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

mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);

System.exit(0);



查看完整回答
反对 回复 2019-11-16

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信