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時尤其有用