Android应用程序类的启动屏幕

5

我有一个Android应用程序,在其中扩展了基本的Application类,以设置一些全局变量。

public class MyApplication extends Application {

 private ArrayList<ModelClass> master_list; // global variable 1
 private DataBaseHelper db_helper; // global variable 2

 @Override
 public void onCreate() {
  super.onCreate();
  //do database work that will take about 5 seconds
 }
}

我希望在应用程序类运行时(即在我的主Activity创建之前)向用户展示一个启动页面。有没有办法实现这个功能?

4个回答

5
你可以将SplashActivity设为启动活动。
当MyApplication完成其工作时,你可以启动你的主活动并关闭闪屏界面。
但不要在onCreate中执行繁重的数据库操作,创建另一个函数并在那里执行操作,否则你的闪屏活动将无法显示。
public class SplashActivity extends Activity
    @override
    protected void onResume() {
    //Create a thread
    new Thread(new Runnable() {
            public void run() {
                //Do heavy work in background
                ((MyApplication)getApplication()).loadFromDb();
                startActivity(new Intent(SplashActivity.this, MainActivity.class));
                finish(); //End this activity
            }
        }).start();
    }
}

抱歉,在您写评论的时候我改变了我的答案。我不知道是否可以从MyApplication启动一个活动,但是我的修改后的答案会启动闪屏界面,然后启动MyApplication工作,完成后启动主活动并关闭闪屏界面。因此,从主活动点击返回按钮将退出应用程序。 - MatteKarla
@MatteKarla:我不确定你是否可以从后台线程调用finish()。我建议使用 AsyncTask,将 loadFromDb() 工作放在 doInBackground() 方法中,并将 startActivity()finish() 放在 onPostExecute() 中。但是,你的一般方法是正确的……针对 OP 提出的字面问题。就个人而言,我希望 OP 重新设计应用程序,以便 loadFromDb() 可以在用户使用应用程序时进行某些操作。闪屏界面对用户来说很烦人,并且是开发人员的拐杖,我认为这样。 - CommonsWare
@user141146:我会尝试弄清楚为什么所有这些都需要在RAM中。单例或Application中的内容应该是缓存,而不是活动数据存储。请记住,您的应用程序可能随时被操作系统或用户无预警地终止。 - CommonsWare
1
@MatteKarla,这个提议的答案没有考虑到当Android操作系统在后台杀死应用程序进程时的情况——例如当用户在接听电话时,操作系统可能会杀死该进程——当用户返回应用程序时,存储的数据将为空,这可能会导致空指针异常。 - M.ES
@M.ES 你说得对,那么这个问题的解决方案是什么,当应用程序被内存回收时,我们如何让应用程序再次从启动屏幕启动...? - Leo K
显示剩余4条评论

3
我在我的应用程序中实现这一点的方式是让主活动扩展ActivityGroup。
public class App extends ActivityGroup {
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.splashscreen);
        new Thread(new Runnable() {
            public void run() {
                // do your loading here
                final LocalActivityManager lam = getLocalActivityManager();
                runOnUiThread(new Runnable() {
                    public void run() {
                        Intent mainIntent = new Intent(MainActivity.class, App.this);
                        Window w = lam.startActivity("main", mainIntent);
                        setContentView(w.getDecorView());
                    }
                }
            }
        }, "App loading thread").start();
    }
}

这样,当应用程序恢复时,您立即获得应用程序,而不是启动画面,并且只加载数据一次(在应用程序启动时)。

实际上,我使用这种方法确保用户在应用程序启动时已登录,如果用户名/密码组合不正确,则不会启动主应用程序,而是启动登录屏幕 :)


0
首先,我认为有许多方法来实现启动画面。直觉上,我不会为了加载特定信息而创建一个特殊的类/活动,因为要保留该信息,您将不得不在某个地方保持该活动处于活动状态- 占用资源。
我会将启动画面设置为一个布局,最初在主活动的onCreate()中加载,然后一旦加载了DB信息,就将您的布局更改为主活动的布局。
例如:
public void onCreate() {
    super.onCreate();
    setContentView(R.layout.splashscreen);
    //do database work that will take about 5 seconds
    setContentView(R.layout.mainscreen)
}

2
布局要在onCreate和onResume完成后才会显示,所以我认为你需要在后台线程上执行它,并让启动页活动自行启动。 - MatteKarla
嗨,谢谢你的建议。我不认为它有效(至少没有使用某种类型的线程),因为只有第二个内容视图会显示出来(布局的渲染仅在onCreate函数完成后才会发生,因此第一次调用setContentView没有明显的效果)。 - user141146

0

我知道这个问题已经过去了很久,但我希望有人会发现这个有用,并且如果需要,我将提供代码。我的方法是在应用程序类中创建一个名为“finishedLoading”的公共布尔值。我将应用程序启动到我的闪屏屏幕活动中,并且每250毫秒检查一次是否finishedLoading = true,当它完成时,我启动新的活动。另一个好处是我有一个小的旋转进度条,所以用户可以看到一些事情正在发生和动画。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接