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()
.
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- package com.pat.welcome;
- import Android.app.Activity;
- import Android.os.Bundle;
- public class WelcomeActivity extends Activity
- {
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- //setContentView(R.layout.main); // 把这一句改为下面一句,用以显示欢迎界面
- setContentView(R.layout.welcome);
- // 下面是模拟数据处理需要5秒钟的时间
- try
- {
- Thread.sleep(5000);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- setContentView(R.layout.main); // 显示真正的应用界面
- }
- }
你将会发现,欢迎界面根本没有出现。在本该出现欢迎界面的时候,界面上什么也没有,过了几秒钟(程序中指定的5秒钟),然后就直接显示真正的应用界面;如果把上面程序中的两条setContentView语句的位置互换,程序开始运行的时候界面上什么也没有,过了几秒钟(程序中指定的5秒钟),然后就直接显示欢迎界面。从现象上看,似乎只有最后那个setContentView语句才会起作用。事实上,的确是这样的。setContentView方法所指定的View,只有在onCreate方法返回后才会显示在界面上。因此,如果调用了两次setContentView方法,只有最后一次才是有效的。 那么怎样解决我们在开始提出的问题呢?即应用启动的时候,显示欢迎界面,过几秒后,再显示真正的应用程序界面呢?下面的解决办法,供大家参考,具体做法:
[java] view plain copy- package com.pat.welcome;
- import Android.app.Activity;
- import Android.os.Bundle;
- import Android.os.Handler;
- import Android.os.Message;
- public class WelcomeActivity extends Activity
- {
- private Handler handler; // 声明handler
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- //setContentView(R.layout.main);// 把这一句改为下面一句
- setContentView(R.layout.welcome);
- // 初始化handler
- handler = new Handler()
- {
- @Override
- public void handleMessage(Message msg)
- {
- if(msg.what == 1) // handler接收到相关的消息后
- {
- setContentView(R.layout.main);// 显示真正的应用界面
- }
- }
- };
- // 新建一个线程,过5秒钟后向handler发送一个消息
- Runnable runnable = newRunnable()
- {
- public void run()
- {
- try
- {
- Thread.sleep(5000);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- handler.sendEmptyMessage(1);//曾想注掉这句话,直接调用setContentView(R.layout.main),但报异常
- }
- };
- Thread thread = new Thread(runnable);
- thread.start();
- }
- }
这样就可以做到先显示欢迎界面5秒钟,然后再显示真正的应用程序界面。
更多相关文章
- android 界面控件被输入法顶起来解决
- android 登录界面
- Android RectF类的构造函数参数说明
- Android 分享一个流量显示界面
- Android 自定义Dialog时出现成员变量为null的问题
- android 读取SD卡或者其他地方文件功能函数