我想在我的应用程序第一次启动时启动一个Activity,从那时起,应用程序应该每次启动另一个(启动器)活动。所以我实施了一个基于this SO answer的解决方案。
解决方案围绕boolean
首选项(以下代码中具有startedBeforePreferenceKey
的键)。在启动器活动的onCreate()
中,我尝试使用密钥startedBeforePreferenceKey
检索首选项,并将其存储在变量startedBefore
中。如果首选项不存在,则会为startedBefore
分配false
。
然后我检查startedBefore
是否false
,如果是,我创建提到的首选项,给它一个值true
并将其存储在{{1} } ,并启动此活动,该活动应首次启动应用程序。这样,当下次执行SharedPreferences
时执行此检查时,onCreate()
将被分配startedBefore
,因此此启动一次活动将无法启动。
问题是当应用程序首次启动时,正常的启动程序会在活动之前显示,该应用程序仅在第一次启动应用程序时启动应用程序已经开始了。
第一次启动应用时,普通启动器根本不会显示。直接,我想在首次启动应用时展示的特殊活动应该显示。
我该怎么办?
true
编辑: @HammadTariqSahi
首先,这段摘自LogCat:
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean startedBefore = sharedPreferences.getBoolean(getString(R.string.startedBeforePreferenceKey), false);
if (!startedBefore) {
SharedPreferences.Editor sharedPreferencesEditor = sharedPreferences.edit();
sharedPreferencesEditor.putBoolean(getString(R.string.startedBeforePreferenceKey), true);
sharedPreferencesEditor.commit();
startActivity(new Intent(this, MainActivity.class));
}
GlobalActivity.java:
03-16 08:42:25.629: E/AndroidRuntime(1837): FATAL EXCEPTION: main
03-16 08:42:25.629: E/AndroidRuntime(1837): Process: tests.globalactivitytest, PID: 1837
03-16 08:42:25.629: E/AndroidRuntime(1837): java.lang.RuntimeException: Unable to instantiate application tests.globalactivitytest.activity.GlobalActivity: java.lang.ClassNotFoundException: Didn't find class "tests.globalactivitytest.activity.GlobalActivity" on path: DexPathList[[zip file "/data/app/tests.globalactivitytest-1/base.apk"],nativeLibraryDirectories=[/data/app/tests.globalactivitytest-1/lib/x86, /vendor/lib, /system/lib]]
03-16 08:42:25.629: E/AndroidRuntime(1837): at android.app.LoadedApk.makeApplication(LoadedApk.java:578)
03-16 08:42:25.629: E/AndroidRuntime(1837): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4680)
03-16 08:42:25.629: E/AndroidRuntime(1837): at android.app.ActivityThread.-wrap1(ActivityThread.java)
03-16 08:42:25.629: E/AndroidRuntime(1837): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
03-16 08:42:25.629: E/AndroidRuntime(1837): at android.os.Handler.dispatchMessage(Handler.java:102)
03-16 08:42:25.629: E/AndroidRuntime(1837): at android.os.Looper.loop(Looper.java:148)
03-16 08:42:25.629: E/AndroidRuntime(1837): at android.app.ActivityThread.main(ActivityThread.java:5417)
03-16 08:42:25.629: E/AndroidRuntime(1837): at java.lang.reflect.Method.invoke(Native Method)
03-16 08:42:25.629: E/AndroidRuntime(1837): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
03-16 08:42:25.629: E/AndroidRuntime(1837): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
03-16 08:42:25.629: E/AndroidRuntime(1837): Caused by: java.lang.ClassNotFoundException: Didn't find class "tests.globalactivitytest.activity.GlobalActivity" on path: DexPathList[[zip file "/data/app/tests.globalactivitytest-1/base.apk"],nativeLibraryDirectories=[/data/app/tests.globalactivitytest-1/lib/x86, /vendor/lib, /system/lib]]
03-16 08:42:25.629: E/AndroidRuntime(1837): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
03-16 08:42:25.629: E/AndroidRuntime(1837): at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
03-16 08:42:25.629: E/AndroidRuntime(1837): at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
03-16 08:42:25.629: E/AndroidRuntime(1837): at android.app.Instrumentation.newApplication(Instrumentation.java:981)
03-16 08:42:25.629: E/AndroidRuntime(1837): at android.app.LoadedApk.makeApplication(LoadedApk.java:573)
03-16 08:42:25.629: E/AndroidRuntime(1837): ... 9 more
03-16 08:42:25.629: E/AndroidRuntime(1837): Suppressed: java.lang.ClassNotFoundException: tests.globalactivitytest.activity.GlobalActivity
03-16 08:42:25.629: E/AndroidRuntime(1837): at java.lang.Class.classForName(Native Method)
03-16 08:42:25.629: E/AndroidRuntime(1837): at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
03-16 08:42:25.629: E/AndroidRuntime(1837): at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
03-16 08:42:25.629: E/AndroidRuntime(1837): at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
03-16 08:42:25.629: E/AndroidRuntime(1837): ... 12 more
03-16 08:42:25.629: E/AndroidRuntime(1837): Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
MainActivity.java:
package tests.globalactivitytest;
import android.app.Application;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class GlobalActivity extends Application {
@Override
public void onCreate() {
super.onCreate();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
//SharedPreferences.Editor editor = sharedPreferences.edit();
boolean launchedBefore = sharedPreferences.getBoolean("launchedBefore", false);
if (launchedBefore) {
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} else {
Intent intent = new Intent(this, LaunchOnceActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
}
LaunchOnceActivity.java:
package tests.globalactivitytest;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
清单文件:
package tests.globalactivitytest;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class LaunchOnceActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launch_once);
}
}
答案 0 :(得分:3)
您可以创建一个启动活动,并从其onCreate方法检查下一个要运行的活动,等待几秒钟,启动活动,然后立即完成启动。
如果您不想创建启动画面,则创建一个没有GUI内容和半透明主题的虚假启动活动,并在onCreate中进行路由,然后立即完成。这将是如此之快,用户不会注意到。
答案 1 :(得分:2)
以上答案也没问题,但如果您需要在没有启动活动的情况下执行此操作,则可以使用以下方法
第1步:创建一个新类并从Application扩展并添加以下代码(不要忘记相应地更改您的活动名称)。其中最重要的部分是在开始任何活动之前设置适当的Intent Flags。
此GlobalActivity将在您的启动器活动
之前调用public class GlobalActivity extends Application {
@Override
public void onCreate() {
super.onCreate();
SharedPreferences userInfo = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = userInfo.edit();
boolean logedIn = userInfo.getBoolean("loggedIn", false);
if (logedIn)
{
Intent intent = new Intent(this,MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
else {
Intent intent = new Intent(this,LaunchOnceActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
}
第2步: 您的清单文件应如下所示
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app.appid" >
<application
android:name=".GlobalActivity"
android:allowBackup="true"
android:icon="@drawable/launch"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".LaunchOnceActivity"
android:label="Launch Once" >
</activity>
</application>
</manifest>
然后相应地更改任何活动中的loggedIn varibale以供将来使用。
答案 2 :(得分:1)
您可以将活动和普通启动器包装成碎片。然后,在onCreate中使用fragmentmanager创建另一个活动,并始终将其作为启动器。在将正确的片段放在该活动的屏幕上之前检查首选项。