在引导完成时启动 Android 应用程序:我的解决方案是否过于复杂?

Starting Android application at boot completion: is my solution overly complicated?

我有一个应用程序,我希望它在引导完成后自动启动。下面的代码似乎过于复杂,当我滑动到相邻的工作区时,应用程序启动不稳定。

我在这里错过了什么?我有一个 activity class、一个服务 class,以及一个广播接收器。下面是我的代码(按顺序),然​​后是清单。

public class BlueDoor extends Activity implements OnClickListener{  
Button btnExit;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);     

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    setContentView(R.layout.main);

    btnExit = (Button) this.findViewById(R.id.ExitButton);  
    btnExit.setOnClickListener(this);
}   

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.ExitButton:
        System.exit(0);
        break;
    }
 }
}

service.class

 public class BlueDoorStartService extends Service {
 @Override
 public IBinder onBind(Intent intent) {
  return null;
 }

 @Override
 public void onCreate() {
  super.onCreate();
  Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();

  Intent callIntent = new Intent(Intent.ACTION_CALL); 
  callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
  callIntent.setClass(this, BlueDoor.class);
  startActivity(callIntent); 
  // do something when the service is created
 }
}

广播接收器

public class StartBlueDoorAtBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

    if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
        Intent serviceIntent = new Intent(context, BlueDoorStartService.class);
        context.startService(serviceIntent);
    }
 }
}

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bluedoor"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="21" />
<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <receiver 
    android:name=".StartBlueDoorAtBootReceiver"
    android:enabled="true"
    android:exported="false" >
    <intent-filter>
     <action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

    <service android:name=".BlueDoorStartService" >
    </service>

    <activity
        android:name=".BlueDoor"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

更新解决方案,2015 年 10 月 22 日:

将服务更改为:

public class BlueDoorStartService extends Service {
@Override
public IBinder onBind(Intent intent) {
    throw new UnsupportedOperationException("Not yet implemented");   
}
@Override
public void onCreate() {
    super.onCreate();
}
@Override
    public void onDestroy() {
       super.onDestroy();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {      
    return super.onStartCommand(intent, flags, startId);
    }
}

接收方:

public class StartBlueDoorAtBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
        // Start Service On Boot Start Up
        Intent serviceIntent = new Intent(context, BlueDoorStartService.class);
        context.startService(serviceIntent);
        //Start App On Boot Start Up
        Intent App = new Intent(context, BlueDoor.class);
        App.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(App);
   }
}

导致使用服务 w/no 行为不当的工作配置。 但是 一起删除服务并修改接收器:

public class StartBlueDoorAtBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
        Intent App = new Intent(context, BlueDoor.class);
        App.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(App);
}
}

还产生了在启动完成后启动应用程序的功能和更简洁的配置。

您的 BroadcastReceiver 调用

context.startService(serviceIntent)

因此,如果服务尚不存在(启动后不久就会出现这种情况),则会创建该服务,从而从其 onCreate() 方法启动 activity。所以该应用程序在一定程度上可以正常工作。

但是当您调用 startService() 时,系统总是调用服务的 onStartCommand() 方法。您没有覆盖该方法,因此系统使用 class android.app.Service 中的标准实现。

正如您在 grepcode.com 上看到的那样,该方法将 return 默认情况下类似于 START_STICKY 的值。这告诉系统保持服务活动,直到它被明确停止。

在你的情况下,我想系统通过暂时终止然后重新激活(=创建)服务来响应滑动,这反过来又启动了你的activity。

可以找到有关服务生命周期的一些信息here

你能做什么: 覆盖 onStartCommand() 以从那里而不是从 onCreate() 开始 activity。然后像 here

中描述的那样使用 stopSelf(int)

最后一件事:当退出 activity 时,不要使用 System.exit(0) 而是调用 finish(),请参阅 "why" 的 SO 答案。