【问题标题】:Android Splash screen for "Application" class“应用程序”类的 Android 启动画面
【发布时间】:2011-04-19 13:07:46
【问题描述】:

我有一个 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
 }
}

我想在 Application 类工作时(即在我的 Main Activity 创建之前)向用户显示启动画面。有没有办法做到这一点?

【问题讨论】:

    标签: android android-activity splash-screen


    【解决方案1】:

    您可以将 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();
        }
    }
    

    【讨论】:

    • 我认为这行不通。我希望事件序列是:1)实例化 MyApplication 类...2)在 MyApplication 的 onCreate() 函数运行时显示“启动画面/忙碌信号”...3)启动主活动。您的建议是在 MyApplication 类完成其业务之后调用“启动屏幕”,但是启动屏幕显示为时已晚。或者我可能没有正确考虑这个问题?
    • 抱歉,在您撰写评论时更改了我的答案。不知道您是否可以从 MyApplication 启动活动,但我修改后的答案会启动启动画面,启动 MyApplication-work,完成后它会启动主要活动并处理启动画面。所以点击主活动的后退按钮会退出应用程序
    • @MatteKarla:我不确定你是否可以从后台线程调用finish()。我建议使用AsyncTask,在doInBackground() 方法中使用loadFromDb(),在onPostExecute() 中使用startActivity()finish()。但是,您的一般方法是合理的……对于 OP 提出的字面问题。就个人而言,我希望 OP 重新设计应用程序,以便loadFromDb() 可以在用户使用应用程序执行 某事 时继续。闪屏对用户来说很烦人,并且是开发人员的拐杖,恕我直言。
    • @CommonsWare。也谢谢。我从来不知道 AsyncTask 存在。至于我的拐杖……我不确定我能做些什么。在用户可以做任何事情之前,我需要将数据(大约 10,000 行数据库数据)加载到内存中并可供所有应用程序的活动(即,需要全局可用)......但也许我没有认真思考够了。
    • @MatteKarla 建议的答案没有考虑Android操作系统在应用程序进程不在前台时杀死它的情况 - 例如,在接听电话时操作系统可以杀死进程 - 当用户返回应用程序,存储的数据将为 null,这可能导致 nullPointerException
    【解决方案2】:

    我在我的应用中执行此操作的方法是让您的主要活动扩展 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();
        }
    }
    

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

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

    【讨论】:

      【解决方案3】:

      首先,我认为有很多方法可以创建启动画面。直观地说,我不会有一个特殊的类/活动来加载特定的信息,因为要保留该信息,您必须在某处保持该活动的活力和良好状态——占用资源。

      我希望初始屏幕只是一个布局,最初使用主活动的 onCreate() 加载,然后在加载数据库信息后,将布局更改为主活动布局。

      类似:

      public void onCreate() {
          super.onCreate();
          setContentView(R.layout.splashscreen);
          //do database work that will take about 5 seconds
          setContentView(R.layout.mainscreen)
      }
      

      【讨论】:

      • 布局在 onCreate 和 onResume 完成后才会显示,所以我认为您需要在后台线程上执行此操作并让启动活动自行启动。
      • 嗨。谢谢你的建议。我认为它不起作用(至少没有某种类型的线程),因为只有第二个内容视图会显示出来(布局的渲染只会在 onCreate 函数完成后才会发生,所以你第一次调用 setContentView 没有明显的效果)。
      【解决方案4】:

      我意识到这在被问到之后还很遥远,但我希望有人觉得这很有用,如果需要我会提供代码。我的方法是在名为“finishedLoading”的应用程序类中创建一个公共布尔值。我将应用程序启动到我的启动屏幕活动中,我每 250 毫秒检查一次是否完成加载 = true,当它完成时,我启动新活动。另一个不错的部分是我有一个小微调进度条,因此用户可以看到正在发生的事情和周围的动画。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-07
        • 1970-01-01
        • 2021-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多