標籤:android 非同步 資料 介面 線程
android 非同步任務的一個後台方法本質是開啟一個線程完成耗時操作,其他onPostExecute方法和onPreExecute方法運行在UI主線程用於更新UI介面。為了提高使用者體驗常見的非同步任務載入方式現在總結如下:
1、非同步載入介面效果如下:
關鍵代碼如下所示:
/** * 非同步任務給列表載入資料 */private void fillData(){new AsyncTask<Void,Void,Void>(){@Overrideprotected void onPreExecute() {loading.setVisibility(View.VISIBLE);super.onPreExecute();}@Overrideprotected void onPostExecute(Void result) {loading.setVisibility(View.INVISIBLE);//重新整理介面列表資料if(mAdapter==null){mAdapter=new RubishSmsInfosAdapter();mRubishSms.setAdapter(mAdapter);}else{mAdapter.notifyDataSetChanged();}super.onPostExecute(result);}@Overrideprotected Void doInBackground(Void... params) {if(mInfos==null){mInfos=mRubishSmsInfoDao.findInfosbyPage(maxNum, offset);}else{mInfos.addAll(mRubishSmsInfoDao.findInfosbyPage(maxNum, offset));}try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}}.execute();}
loading對應的
loading=findViewById(R.id.ll_rublish_sms_info_loading);
布局檔案如下:
activity_rubish_sms.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="100" > <LinearLayout android:layout_gravity="center" android:id="@+id/ll_rublish_sms_info_loading" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:visibility="invisible" > <ProgressBar android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:gravity="center" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="資料載入中,請稍後..." android:textSize="13sp" /> </LinearLayout> </FrameLayout> <ListView android:id="@+id/lv_rubish_sms_content" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView></LinearLayout>
通過如上代碼即可實現上述效果。
2、利用對話方塊實現
實現:
非同步任務實現 邏輯代碼:
/** * 掃描病毒 並動態顯示在介面 */private void scanVirus(){new AsyncTask<Void,Object, Void>() {List<VirusApp> apps=new ArrayList<VirusApp>();String desc=null;Dialog dialog=new Dialog(KillVirusActivity.this);View viewKilling=View.inflate(KillVirusActivity.this,R.layout.killing_dialog,null);@Overrideprotected void onPreExecute() {mKillVirusResult.setText("正在掃描中,請稍等...");dialog.setCancelable(false);dialog.setContentView(viewKilling);dialog.show();pm=getPackageManager(); packageInfos=pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES|PackageManager.GET_SIGNATURES);// progressBar.setMax(packageInfos.size());super.onPreExecute();}@Overrideprotected void onPostExecute(Void result) {dialog.dismiss();if(apps.size()>0){mKillVirusResult.setTextColor(Color.RED);mKillVirusResult.setText("掃描完成!發現病毒"+apps.size()+"個"+","+"請及時清理");for(final VirusApp app:apps){//有病毒View view=View.inflate(KillVirusActivity.this,R.layout.app_virus_info_item,null);view.setClickable(true);view.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//卸載程式Intent intent = new Intent();intent.setAction("android.intent.action.DELETE");intent.addCategory(Intent.CATEGORY_DEFAULT);intent.setData(Uri.parse("package:"+ app.getmAppVirusName()));startActivity(intent);}});ImageView appIcon=(ImageView) view.findViewById(R.id.iv_app_icon);TextView appName=(TextView) view.findViewById(R.id.tv_app_name);TextView appDesc=(TextView)view.findViewById(R.id.tv_app_virus_desc);appIcon.setBackground(app.getmAppVirusIcon());appName.setText(app.getmAppVirusName());appDesc.setText(app.getmAPPVirusDesc());mContainer.addView(view);}}else if(apps.size()==0){mKillVirusResult.setText("掃描完成!恭喜沒有發現病毒!");}super.onPostExecute(result);}@Overrideprotected Void doInBackground(Void... params) {int total=0;//獲得資料庫操作對象VirusDao virusDao=new VirusDao();//獲得裝置上所有應用的簽名for(PackageInfo info:packageInfos){ total++;Signature[] signature=info.signatures;try {String md5=Md5Util.encode(signature[0].toString()); desc=virusDao.findVirus(md5);Log.i("殺毒MD5<<<", md5); desc=virusDao.findVirus(md5);} catch (Exception e) {// TODO: handle exception}//Log.i("殺毒<<<", (signature[0]).toString());//簽名用MD5編碼獲得MD5加密後的應用的簽名資訊//Log.i("殺毒MD5<<<", md5);//查詢本地病毒簽名資料庫// desc=virusDao.findVirus(md5); if(desc!=null){//查詢到病毒 VirusApp app=new VirusApp(); //獲得應用的表徵圖Drawable drawable=pm.getApplicationIcon(info.applicationInfo);app.setmAppVirusIcon(drawable); //獲得應用程式名稱String appName=(String) pm.getApplicationLabel(info.applicationInfo);app.setmAppVirusName(appName); //獲得該應用的病毒描述 app.setmAPPVirusDesc(desc); apps.add(app); app=null; //publishProgress(total,app); }else{ Log.i("殺毒MD5<<<","不是病毒"+total); }}//progressBar.setProgress(total);try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}}.execute();}該邏輯處理對應的activity布局介面:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="35dp" android:background="@drawable/ll_title_bg" android:gravity="center" android:text="手機病毒查殺" /> <TextView android:id="@+id/tv_kill_virus_result" android:layout_width="match_parent" android:layout_height="125dp" android:gravity="center" android:background="@drawable/ll_title_bg" /> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" > <LinearLayout <span style="color:#ff0000;"> android:id="@+id/ll_container"</span> android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > </LinearLayout> </ScrollView></LinearLayout>
該介面有一個線性版面配置容器,可以實現動態載入資料的效果。
實現自訂對話方塊的布局:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="病毒掃描中..." android:textSize="15sp" /></LinearLayout>
實現動態掃描並載入資料的整個Activity代碼:
package com.example.yqqmobilesafe;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.app.Dialog;import android.content.Intent;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.content.pm.Signature;import android.graphics.Color;import android.graphics.drawable.Drawable;import android.net.Uri;import android.os.AsyncTask;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.ProgressBar;import android.widget.TextView;import com.example.yqqmobilesafe.db.dao.VirusDao;import com.example.yqqmobilesafe.domain.VirusApp;import com.example.yqqmobilesafe.utils.CopyFileToSystem;import com.example.yqqmobilesafe.utils.Md5Util;//本地病毒查殺public class KillVirusActivity extends Activity {private LinearLayout<span style="color:#ff0000;"> mContainer</span>;private TextView mKillVirusResult;private PackageManager pm;private ProgressBar progressBar;private List<PackageInfo> packageInfos;public KillVirusActivity() {}@Overrideprotected void onCreate(Bundle savedInstanceState) {setContentView(R.layout.activity_kill_virus);<span style="color:#ff0000;">mContainer</span>=(LinearLayout) this.findViewById(R.id.ll_container);mKillVirusResult=(TextView) this.findViewById(R.id.tv_kill_virus_result);//progressBar=(ProgressBar) this.findViewById(R.id.pb_scanning_virus);copyVirusDB();//拷貝本地病毒簽名到系統目錄 scanVirus();super.onCreate(savedInstanceState);}/** * 掃描病毒 並動態顯示在介面 */private void scanVirus(){new AsyncTask<Void,Object, Void>() {List<VirusApp> apps=new ArrayList<VirusApp>();String desc=null;Dialog dialog=new Dialog(KillVirusActivity.this);View viewKilling=View.inflate(KillVirusActivity.this,R.layout.killing_dialog,null);@Overrideprotected void onPreExecute() {mKillVirusResult.setText("正在掃描中,請稍等...");dialog.setCancelable(false);dialog.setContentView(viewKilling);dialog.show();pm=getPackageManager(); packageInfos=pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES|PackageManager.GET_SIGNATURES);// progressBar.setMax(packageInfos.size());super.onPreExecute();}@Overrideprotected void onPostExecute(Void result) {dialog.dismiss();if(apps.size()>0){mKillVirusResult.setTextColor(Color.RED);mKillVirusResult.setText("掃描完成!發現病毒"+apps.size()+"個"+","+"請及時清理");for(final VirusApp app:apps){//有病毒View view=View.inflate(KillVirusActivity.this,R.layout.app_virus_info_item,null);view.setClickable(true);view.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//卸載程式Intent intent = new Intent();intent.setAction("android.intent.action.DELETE");intent.addCategory(Intent.CATEGORY_DEFAULT);intent.setData(Uri.parse("package:"+ app.getmAppVirusName()));startActivity(intent);}});ImageView appIcon=(ImageView) view.findViewById(R.id.iv_app_icon);TextView appName=(TextView) view.findViewById(R.id.tv_app_name);TextView appDesc=(TextView)view.findViewById(R.id.tv_app_virus_desc);appIcon.setBackground(app.getmAppVirusIcon());appName.setText(app.getmAppVirusName());appDesc.setText(app.getmAPPVirusDesc());<span style="color:#ff0000;">mContainer.addView(view);</span>}}else if(apps.size()==0){mKillVirusResult.setText("掃描完成!恭喜沒有發現病毒!");}super.onPostExecute(result);}@Overrideprotected Void doInBackground(Void... params) {int total=0;//獲得資料庫操作對象VirusDao virusDao=new VirusDao();//獲得裝置上所有應用的簽名for(PackageInfo info:packageInfos){ total++;Signature[] signature=info.signatures;try {String md5=Md5Util.encode(signature[0].toString()); desc=virusDao.findVirus(md5);Log.i("殺毒MD5<<<", md5); desc=virusDao.findVirus(md5);} catch (Exception e) {// TODO: handle exception}//Log.i("殺毒<<<", (signature[0]).toString());//簽名用MD5編碼獲得MD5加密後的應用的簽名資訊//Log.i("殺毒MD5<<<", md5);//查詢本地病毒簽名資料庫// desc=virusDao.findVirus(md5); if(desc!=null){//查詢到病毒 VirusApp app=new VirusApp(); //獲得應用的表徵圖Drawable drawable=pm.getApplicationIcon(info.applicationInfo);app.setmAppVirusIcon(drawable); //獲得應用程式名稱String appName=(String) pm.getApplicationLabel(info.applicationInfo);app.setmAppVirusName(appName); //獲得該應用的病毒描述 app.setmAPPVirusDesc(desc); apps.add(app); app=null; //publishProgress(total,app); }else{ Log.i("殺毒MD5<<<","不是病毒"+total); }}//progressBar.setProgress(total);try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}}.execute();}/** * 拷貝本地病毒庫資料庫到app目錄 */private void copyVirusDB(){new AsyncTask<Void,Void,Void>(){@Overrideprotected Void doInBackground(Void... params) {//獲得要拷貝到目的地的檔案File file=new File(getFilesDir(),"antivirus.db");if(file.exists()&&file.length()>0){}else{//獲得檔案輸入資料流InputStream is=null;try {is=getResources().getAssets().open("antivirus.db");CopyFileToSystem.copyFile(is, file.getAbsolutePath());} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return null;}}.execute();}}
android非同步任務載入資料介面實現