Android Activity的onCreate()函数

今天,我们先说一个无处不在的函数:onCreate().。我们看看gogle是怎么解释他的:

Called when the activity is first created. This is where you should do all of your normal static set up: create views, bind data to lists, etc. This method also provides you with a Bundle containing the activity's previously frozen state, if there was one.

Always followed by onStart().

这里我们只关注一句话:This is where you should do all of your normal static set up。其中我们只关注normal static,

normal:常规的、通常的、一般的 。

static:静态的,不变的。

说的是:在这里我们需要做通常需要配置的信息,而不是真的所有的事情都在这里做。我们知道,一个activity启动回调的第一个函数就是onCreate。这个函数主要做这个activity启动的一些必要的初始化的工作,这个函数调用完后,这个activity并不是说就已经启动了,或者是跳到前台了。而是还需要其他的大量工作,我们知道:onCreate之后调用了还有onRestart()和onStart()等,实际上onStart()调用完毕了这个activity还没有完全启动,也只是前台可见,直到 onResume() 后这个onCreate才算终于启动。既然这样,那么在一个activity真正启动之前任何相当耗时的动作都会导致activity启动缓慢,特别是在onCreate里面耗时长的话可能照成严重的体验效果。

我们来先看一个实例:

@Override

protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
     
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    mContext = this;
    setContentView(R.layout.main);
    dataLoad = new DataLoading();
    mScrollLayout = (ScrollLayout)findViewById(R.id.ScrollLayoutTest);
    btnExit = (ImageButton)findViewById(R.id.btn_exit);
    btnExit.setOnClickListener(btnExitClickListener);
    btnContacts = (ImageButton)findViewById(R.id.btn_contacts);
    btnContacts.setOnClickListener(btnContactsClickListener);
     
    mSpeedDailDataMgr = new SpeedDailMgr(this);
    loadGripView();
 
    //in MTK        
       //mCallOptionHandler = new CallOptionHandler(this);
       mCallOptionHandler = new ContactsCallOptionHandler(this,
                new ContactsCallOptionHandlerFactory());        
    //don't consider getting no data, ex: when starting up
    updateEnabledCard();
 
}


这是一个APP的一个Activity的onCreate的写法。其实这段代码没有什么问题,而且看起来也是比较简单的代码。不过里面大量危险的代码段:不管是dataLoad = new DataLoading(); 还是 mSpeedDailDataMgr = new SpeedDailMgr(this);更或者是loadGripView();甚至updateEnabledCard();这么危险的处理都是不应该在这里来处理的。这里包含了加载数据库数据、读取文件信息、读取SIM卡信息,这些操作都是有可能跳出异常的,而且其操作耗时也是不确定的!对于面对这样问题,我觉得应该注意下面几个方面:

(1)在Activity启动前,尽量少做。

(2)对于布局比较复杂的时候,可以考虑不要一次性全部加载上,动态加载是一个好的办法。

(3)对于及时需要的数据,加载起来耗时的又有异常危险的,一定记得开辟一个线程来做这些动作,千万记得不要做阻塞主线程(UI线程)的任何事情。

(4)对于特殊情况下,Activity启动确实需要大量工作时候,可以考虑先加载一个简单的布局(或是Activity)来过渡.。

(5)所有的目的都是让你要启动的组件尽快上场,而不是以画好妆为主,这样的话客人会等不及的,这个社会客户才是上帝。



再来说一下Android中一个Activity的六个主要函数:

onCreate(), onStart(), onResume(),onPause(),onStop(),onDestroy().


onCreate函数:注册你要用到的变量,比如说service,receiver,这些变量是无论你的Activity是在前台还是在后台都能够被响应到的,然后调用上面那个用来初始化的函数初始化布局信息。

onStart函数:注册一些变量。这些变量必须在Android Activity类在前台的时候才能够被响应。

onResume函数:调用一些刷新UI的函数,每当Activity调用到这里时就要刷新一下UI各控件的状态。

onPause函数:一般是做一些变量的设置,因为这个时候Activity马上就要切到后台处理,可能有些变量就要被释放掉或者状态要做些相应的调整。

onStop函数:反注册在onStart函数中注册的变量。

onDestory函数:反注册在onCreate函数中注册的变量。


举个例子:Android-Hello

public class UbiLrnActivity extends Activity{
        /**Called when the activity is first created*/
        @Override 
        public void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
        }
}

首先,生命了一个onCreate函数,这个函数传入的参数是savedInstanceState,Bundle类型。Bundle是一个数据参数,一般用于Activity之间的数据传送,onCreate的参数多事Bundle类的。

super.onCreate表示的是调用父类onCreate

setContentView(R.layout.main)表示的是通过加载main.xml来加载系统的resource。



还有一个例子,是一个应用的情景,转载。

Android实现欢迎页:在onCreate方法中两次调用setContentView

首先,要知道,setContentView方法的用途就是加载布局文件。

        在做Android开发的时候,有时候需要在一个Activity的里面调用两次setContentView方法。比如在应用启动的时候,开始显示欢迎界面,在显示欢迎界面的同时,进行后台数据的处理,等到后台数据准备好了,才显示真正的应用界面。这样的做法不会让使用者有突兀的感觉。反之,应用已启动就显示真正的应用界面,但在后续的操作需要准备数据的时候,假定是5秒钟,那么在这5秒钟内使用者将无法使用该应用,这样用户界面显然是不够友好的。
        为了实现欢迎界面,大家很自然地就会想到:在onCreate方法中,调用两次setContentView。是的,要调用两次setContentView,但怎么调用还是有点技巧,而不是简单地调用两次setContentView就可以解决问题的。下面,我们就用实际的例子来给予说明。

        下面来完善WelcomeActivity.java的代码,如果我们像下面这样直接写:

[java]  view plain copy
  1. package com.pat.welcome;  
  2. import Android.app.Activity;  
  3. import Android.os.Bundle;  
  4. public class WelcomeActivity extends Activity  
  5. {  
  6.        @Override  
  7.        public void onCreate(Bundle savedInstanceState)  
  8.        {  
  9.             super.onCreate(savedInstanceState);  
  10.             //setContentView(R.layout.main);    // 把这一句改为下面一句,用以显示欢迎界面  
  11.               setContentView(R.layout.welcome);  
  12.             // 下面是模拟数据处理需要5秒钟的时间  
  13.               try  
  14.             {  
  15.                     Thread.sleep(5000);  
  16.             }   
  17.             catch (InterruptedException e)  
  18.             {  
  19.                     e.printStackTrace();  
  20.             }  
  21.             setContentView(R.layout.main);                  // 显示真正的应用界面  
  22.        }  
  23. }  

你将会发现,欢迎界面根本没有出现。在本该出现欢迎界面的时候,界面上什么也没有,过了几秒钟(程序中指定的5秒钟),然后就直接显示真正的应用界面;如果把上面程序中的两条setContentView语句的位置互换,程序开始运行的时候界面上什么也没有,过了几秒钟(程序中指定的5秒钟),然后就直接显示欢迎界面。从现象上看,似乎只有最后那个setContentView语句才会起作用。事实上,的确是这样的。setContentView方法所指定的View,只有在onCreate方法返回后才会显示在界面上。因此,如果调用了两次setContentView方法,只有最后一次才是有效的。 那么怎样解决我们在开始提出的问题呢?即应用启动的时候,显示欢迎界面,过几秒后,再显示真正的应用程序界面呢?下面的解决办法,供大家参考,具体做法:                                  

[java]  view plain copy
  1. package com.pat.welcome;  
  2. import Android.app.Activity;  
  3. import Android.os.Bundle;  
  4. import Android.os.Handler;  
  5. import Android.os.Message;  
  6. public class WelcomeActivity extends Activity  
  7. {  
  8.        private Handler handler; // 声明handler  
  9.        @Override  
  10.        public void onCreate(Bundle savedInstanceState)  
  11.        {  
  12.                     super.onCreate(savedInstanceState);  
  13.                     //setContentView(R.layout.main);// 把这一句改为下面一句  
  14.                        setContentView(R.layout.welcome);  
  15.                     // 初始化handler  
  16.                     handler = new Handler()  
  17.                     {  
  18.                              @Override  
  19.                              public void handleMessage(Message msg)  
  20.                              {  
  21.                                  if(msg.what == 1// handler接收到相关的消息后  
  22.                                       {  
  23.                                      setContentView(R.layout.main);// 显示真正的应用界面  
  24.                                       }  
  25.                              }  
  26.                     };  
  27.                     // 新建一个线程,过5秒钟后向handler发送一个消息  
  28.                        Runnable runnable = newRunnable()  
  29.                     {  
  30.                              public void run()  
  31.                              {  
  32.                                       try  
  33.                                       {  
  34.                                                 Thread.sleep(5000);  
  35.                                       }   
  36.                                       catch (InterruptedException e)  
  37.                                       {  
  38.                                                 e.printStackTrace();  
  39.                                       }  
  40.                                       handler.sendEmptyMessage(1);//曾想注掉这句话,直接调用setContentView(R.layout.main),但报异常  
  41.                              }  
  42.                     };  
  43.                     Thread thread = new Thread(runnable);  
  44.                     thread.start();             
  45.     }  
  46. }  

这样就可以做到先显示欢迎界面5秒钟,然后再显示真正的应用程序界面。


  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值