版權聲明:未經博主允許不得轉載 AsyncTask 瞭解AsyncTask非同步,需要瞭解一下非同步任務(多線程),什麼是線程,可以這麼說線程好比邊吃飯邊看電視,AsyncTask是為了方便後臺線程中操作更新UI,本質為Handler非同步消息處理機制。 學習AsyncTask需要知道它的參數,它要實現的 ...
版權聲明:未經博主允許不得轉載
AsyncTask
瞭解AsyncTask非同步,需要瞭解一下非同步任務(多線程),什麼是線程,可以這麼說線程好比邊吃飯邊看電視,AsyncTask是為了方便後臺線程中操作更新UI,本質為Handler非同步消息處理機制。
學習AsyncTask需要知道它的參數<Params,Progress,Result>,它要實現的方法onPreExcecute(),onPostExecute(),後臺線程操作doInBackground();顯示進度onProgressUpdate()等方法。在這裡混個眼熟,下麵會用代碼講一下如何用。
在這裡我們創建一個類
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//這裡創建一個內部類繼承AsyncTask
public class DownloadAsyncTask extends AsyncTask<String,Integer,Boolean>{
}
}
我們在這裡點擊去看底層AsyncTask
public abstract class AsyncTask<Params, Progress, Result> {
//其中Params為類型參數,Progress為進度,為返回結果
}
在這裡繼承,實現的方法有
//在非同步任務之前
@Override
protected void onPreExecute() {
super.onPreExecute();
// 準備工作
}
@Override
protected Boolean doInBackground(String... strings){
//處理事件
}
@Override
protected void onPostExecute(Boolean aBoolean){
super.onPostExecute(aBoolean);
//執行完,執行結果 處理
}
//當我們的進度在變化的時候
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
//收到進度,然後處理:也是在UI線程中。
}
//取消
/*@Override
protected void onCancelled(Boolean aBoolean) {
super.onCancelled(aBoolean);
}
@Override
protected void onCancelled() {
super.onCancelled();
}*/
在這裡通常執行onPreExcecute(執行前),doInBackground(執行中),onPostExecute(執行後),onProgressUpdate這些方法。
在這裡寫個例子,如何下載一個從網路上下載一個apk,請求網路數據下載文件。在這裡我會比較詳細地講解一下如何獲取url,以及請求網路的事情。
設置一個點擊下載文件的按鈕
//定義一個方法
private void setButtonListener(){
mDownloadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DownloadAsyncTask asyncTask = new DownloadAsyncTask();
asyncTask.execute(APK_URL);
}
});
}
在這裡講解一下,申請asyncTask應用可以理解,就是在創建對象嘛,public class DownloadAsyncTask extends AsyncTask<String,Integer,Boolean>{...}
,那麼這個'execute'還沒講,那就點擊進入看一下源碼吧~
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
//通過execute實現
下麵就進入執行中的代碼
//解釋一下這裡的Boolean是由這個定義的
public class DownloadAsyncTask extends AsyncTask<String,Integer,Boolean>{
}
//<Params, Progress, Result>
//String... strings 表示數組,可變參數,可能為空
@Override
protected Boolean doInBackground(String... strings){
}
執行前
@Override
protected void onpreExecute(){
super.onPreExecute();
//解決UI問題
}
執行中的代碼,進行下載:
//String... 為數組
@Override
protected Boolean doInBackground(String... strings) {
//預防為空
if (strings != null && strings.length>0){
//傳入的參數是url,由上面的
// DownloadAsyncTask asyncTask = new DownloadAsyncTask();
//asyncTask.execute(APK_URL);
//決定
String apkurl = strings[0];
try{
//給你一個下載地址url,那麼你就要創建一個url對象
URL url = new URL(apkurl);//String apkurl = strings[0];
//構造一個URLConnection 打開連接 url.openConnection()
URLConnection urlConnection = url.openConnection();
//輸入流 讀取數據
InputStream inputStream = urlConnection.getInputStream();
//接下來獲取下載內容的總長度
int contentLength = urlConnction.getContentLength();
//接下來就是找個地方存放,就跟放在目錄哪裡一下,為字元串
String mFilePath=Environment.getExternalStorageDirectory() + File.separator + FILE_NAME;
// Environment.getExternalStorageDirectory() 為目錄,比較實用
// File.separator 相當'//'
// FILE_NAME為文件名,可改為“what.apk”.
//對下載地址進行處理
File apkFile = new File(mFilePath);
//接下來就是文件輸入到目錄中
//先讀取再寫入
//判斷文件
if(apkFile.exists()){
boolean result = apkFile.delete();
if(!result){
return false;
}
}
//文件進度條,已經下載了多少
int downloadSize = 0;
//定義一個讀取數組長度,接下來進行。。。
byte[] bytes = new byte[1024];//1024沒有規定,可以自己決定
//讀取多長
int length;
//創建一個輸出流,寫
OutputStream outputStream = new FileOutputStream(mFilePath);//寫到這個路徑
while( (length = inputStream.read(bytes)) != -1){
outputStream.write(bytes,0,length);
downloadSize+=length;
//發送進度
publishProgress();
}
....
}
}
執行後
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
//也是在主線程中,執行結果 處理
//處理UI
}
最後進度變化
//當我們的進度在變化的時候
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if (values != null && values.length >0){
}
}
重點要添加網路許可權以及讀取許可權
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
ListView
ListView是我們在Android開發中常用到的一個控制項,用來展示數據,我們在微信列表項,文章列表隨處可見。
深入瞭解
public class AppListAdapter extends BaseAdapter{}
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {}
public interface ListAdapter extends Adapter {}
public interface SpinnerAdapter extends Adapter {}
創建佈局
<ListView
android:id="@+id/main_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
實現控制項聲明
private ListView mListView;
mListView=findViewById(R.id.main_list_view);
步驟:瞭解一下Adapter(適配器)
public class AppListAdapter extends BaseAdapter{
}
//獲取包名
String packageName = mAppInfos.get(position).activityInfo.packageName;
////獲取應用名
String className = mAppInfos.get(position).activityInfo.name;
//拼接-點擊方法
ComponentName componentName = new ComponentName(packageName,className);
final Intent intent = new Intent();
//通過Intent設置組件名
intent.setComponent(componentName);
startActivity(intent);
BaseAdapter中抽象方法
public int getCount();
public Object getItem(int arg0);
public long getItemId(int arg1);
public View getView(int position, View convertView, ViewGroup parent);
public View getView(int position, View covertView, ViewGroup parent){
if(converView == null){
converView = mInflater.inflate(R.layout.list_item, null);
}
}
static class ViewHolder{
public ImageView image;
public TextView title;
}
@Override
public View getView(int position,view convertView, ViewGroup parent){
ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.list_item, null);
holder.
holder.
convertView.setTag(holder);
}else{
holder=(ViewHolder)convertView.getTag();
}
}
編輯 :達叔
定位:分享 Android&Java 知識點