问题:在准备好使用我的应用之前,我需要在每次启动时运行一些代码。
起初,我尝试在专门的活动中做到这一点。
AndroidManifest.xml
<activity android:name=".MainActivity" />
<activity android:name=".StarterActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
AppLoader.java
public class AppLoader {
private static Object someInstance;
public static void load(Runnable onCompleteCallback) {
try {
someInstance = new Object();
//potentially long operation to initialize the app
Thread.sleep(5000);
onCompleteCallback.run();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public static void checkInitialized() {
if (someInstance == null) {
throw new RuntimeException("Not initialized");
}
}
}
StarterActivity.java
public class StarterActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AppLoader.load(() -> {
MainActivity.start(this);
finish();
});
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
public static void start(Context context) {
Intent starter = new Intent(context, MainActivity.class);
context.startActivity(starter);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AppLoader.checkInitialized();
}
}
如果该应用是通过启动器图标冷启动的,但在所有其他情况下崩溃,则可以正常工作。重现问题的简单方法:
这是一篇描述类似问题的文章:Android process death — and the (big) implications for your app
可能的解决方案:
那么,每次启动应用程序时运行一些代码的正确方法是什么?
注意:通常StarterActivity将是一个初始屏幕,AppLoader将被注入,等等,但是为了简单起见,我省略了它。
答案 0 :(得分:0)
AndroidManifest.xml
Sub GetInfo()
Const Url$ = "https://www.austrade.gov.au/SupplierDetails.aspx?ORGID=ORG0120000508&folderid=1736"
Dim Http As New XMLHTTP60, rxp As New RegExp
With Http
.Open "GET", Url, False
.send
End With
With rxp
.Pattern = "Company Name:(\s[\w\s]+)"
If .Execute(Http.responseText).Count > 0 Then
[A1] = .Execute(Http.responseText)(0).SubMatches(0)
End If
.Pattern = "Phone:(\s\+[\d\s]+)"
If .Execute(Http.responseText).Count > 0 Then
[B1] = .Execute(Http.responseText)(0).SubMatches(0)
End If
.Pattern = "Fax:(\s\+[\d\s]+)"
If .Execute(Http.responseText).Count > 0 Then
[C1] = .Execute(Http.responseText)(0).SubMatches(0)
End If
End With
End Sub
AppLoader.java
<application
android:name=".AppLoader"
更新
-在启动画面上使用public class AppLoader extends Application {
private static Object someInstance;
@Override
public void onCreate() {
super.onCreate();
// DO YOUR STUFF
}
}
。
Handler
答案 1 :(得分:0)
您的应用抛出了您在AppLoader.checkInitialized()方法中设置的RuntimeException,因为当应用进入后台并被系统杀死时,someInstance对象将丢失其状态(因为您已将设备设置为保持零后台线程)。因此,当您尝试重新打开应用程序时,系统将直接启动MainActivity(而不是StarterActivity),因为它正在尝试恢复其先前状态。但是变量无法恢复,甚至静态变量也无法恢复。
因此,如果您在MainActivity上需要Object SomeInstance,则应将其实例化集成到MainActivitie的生命周期中,并覆盖诸如onSavedInstanceState,onRestoreInstanceState等之类的方法,以在您的应用被系统杀死后正确处理并重新加载该对象。 / p>
看看这个https://developer.android.com/guide/components/activities/activity-lifecycle
答案 2 :(得分:0)
如果有人感兴趣,我最终只是在需要时将用户重定向到StarterActivity,以确保每次启动都执行必要的代码。
public abstract class BaseActivity extends AppCompatActivity {
private boolean isCreated;
@Override
protected final void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!appLoader.isLoaded()) {
StarterActivity.start(this);
finish();
return;
}
onCreateActivity(savedInstanceState);
isCreated = true;
}
protected void onCreateActivity(@Nullable Bundle savedInstanceState) {
}
@Override
protected final void onDestroy() {
super.onDestroy();
if (isCreated) {
onDestroyActivity();
}
}
protected void onDestroyActivity() {
}
}
所有活动都扩展了BaseActivity(StarterActivity除外),并覆盖了onCreateActivity / onDestroyActivity而不是onCreate / onDestroy。