1、跳转的界面,即第二个Activity的执行将消耗一定的系统资源和时间,在这之前页面不会显示(黑屏)。对于资源消耗少的页面尚可接受,但是对于大量资源消耗而导致的长时间黑屏,将大大降低用户的友好性。
2、为了增加用户的友好性,一种可行的办法是使用异步任务(AsyncTask)和等待提示相结合,告诉用户系统正在运行。但是如何封装一个公用的模式,供应用程序使用呢?
本文将通过一个例子来说明。其中核心的思想时异步任务,即AsyncTask启动一个背景Thread, 并在工作完成的时候将控制权交还给UI Thread. 示例:
首先定义一个后台执行和UI更新的运行接口,Excution.java
public interface Excution {
void longExcute();
void uiUpdate();
}
longExcute()方法定义了长时间的后台操作,uiUpdate()方法定义了后台操作完成后的调用方法,以便更新UI主界面。
其次,继承AsyncTask对象,构建LongOperation对象,构造子Excution对象从 Activity传入。在需要执行后台长时间操作时回调longExcute()方法,后台操作完成后回调uiUpdate()方法。而在后台执行的过程 中,系统的提示筐被封装在ProcessDialog对象里。
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
public class LongOperation extends AsyncTask<String, Void, String>{
private static final String TAG = "LongOperation";
private ProgressDialog dialog;
private Context context;
private Excution excution;
private boolean showDialog = true;
public LongOperation(Context context,final Excution excution){
this.context = context;
this.excution = excution;
showDialog = true;
}
public LongOperation setShowDialog(boolean showDialog){
this.showDialog = showDialog;
return this;
}
@Override
protected String doInBackground(String... params) {
// perform long running operation operation
Log.d(TAG,"doInBackground()");
excution.longExcute();
return null;
}
@Override
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
Log.d(TAG,"onPostExecute()");
try{
if(showDialog){
dialog.dismiss();
}
dialog = null;
excution.uiUpdate();
}catch(Exception e){
}
}
@Override
protected void onPreExecute() {
// Things to be done before execution of long running operation. For example showing ProgessDialog
Log.d(TAG,"onPreExecute()");
if(showDialog){
dialog = new ProgressDialog(context);
dialog.setMessage("Loading");
dialog.setTitle("Please wait...");
dialog.show();
}
}
@Override
protected void onProgressUpdate(Void... values) {
// Things to be done while execution of long running operation is in progress. For example updating ProgessDialog
Log.d(TAG,"onProgressUpdate()");
}
public interface Excution {
void longExcute();
void uiUpdate();
}
}
经过以上两个步骤之后,封装基本结束,最后自要在Activity中简单调用即可,如下面的片段代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new LongOperation(this, new Excution() {
@Override
public void longExcute() {
//get data
}
@Override
public void uiUpdate() {
setContentView(R.layout.userinfo);
//set data to UI
}
}).execute(new String[] {});
}
扩展及思考:
1、读者可以根据自身需要修改弹出筐样式,或者自定义View,如果有多种样式,这可以通过构造子传入。
2、如果不需要弹出筐,通过设置setShowDialog(false)方法即可完成,此在页面不跳转,但是又需要后台操作,同时不用阻塞UI时尤其有用