一週沒學習,累覺不愛,週一新刀到手,結果就把手指給切了5MM深1cm寬,直接縫了四針,真是痛苦到極點了!隔一天還得換次藥,現在總算不是太影響敲代碼了,感覺有點爲自己開脫的感覺。花了300多,一週時間,真的很不划算,開始敲代碼吧。。
AsyncTask的學習
AsyncTask就是對Handler和Thread的封裝,簡化了一些操作
常見的方法有四個:
onPreExecute(); 執行在主線程中,異步任務前開始前調用.
doInBackground();執行在子線程中,異步任務的過程中調用.
onPostExecute();執行在主線程中,任務完成後調用.
onProgressUpdate();執行在主線程中,在執行過程中操作進度的改變.
/**
* 異步下載demo
* 1:準備權限相關: 網絡權限 讀寫存儲設備權限
* 2: 界面 Layoout
* 3:下載前要做的事情
* 4:下載中要做的事情
* 5:下載完成後要做的事情
*/
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final int INIT_PROGRESS = 0;
private static final String APK_URL = "http://download.sj.qq.com/upload/connAssitantDownload/upload/MobileAssistant_1.apk";
private static final String APK_NAME = "aaaa.apk";
private ProgressBar mProgressBar;
private Button mButton;
private TextView mDwonLoadText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
initListener();
}
private void initView() {
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mButton = (Button)findViewById(R.id.button);
mDwonLoadText = (TextView)findViewById(R.id.tv_download);
}
private void initData() {
mProgressBar.setProgress(INIT_PROGRESS);//設置進度
mButton.setText(R.string.click_dwonload);
mDwonLoadText.setText(R.string.click_dwonload);
}
private void initListener() {
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//點擊開始下載....執行耗時操作
DwonloadAsyncTask dwonloadAsyncTask = new DwonloadAsyncTask();
//傳入的參數。。 可以是任何參數 這裏一般傳入url地址
dwonloadAsyncTask.execute(APK_URL);
}
});
}
/**
* String 參入的參數
* Integer 進度條的進度
* Boolean 返回值
*/
class DwonloadAsyncTask extends AsyncTask<String,Integer,Boolean>{
//獲取文件存儲的路徑
String apkPash = Environment.getExternalStorageDirectory()+File.separator+ APK_NAME +File.separator;
/**
* 此方法執行在子線程中,是AsnycTask執行的開始方法,在異步任務之前執行
* 一般用來操作ui
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* 此方法執行在子線程中,是AsnycTask的執行過程中的方法
* @param params 入參
* @return 出參
*/
@Override
protected Boolean doInBackground(String... params) {
if (params!=null && params.length>0){
//接受params傳入進來的參數
String apkUrl = params[0];
try {
//創建URL
URL url = new URL(apkUrl);
//創建連接 並打開
URLConnection conn = url.openConnection();
//獲取url的一些參數
//連接文件的總大小
int contentLength = conn.getContentLength();
//獲取文件的輸入流
InputStream is = conn.getInputStream();
//獲取文件存儲的路徑
String apkPash = Environment.getExternalStorageDirectory()+File.separator+ APK_NAME +File.separator;
File file = new File(apkPash);
//對文件路徑做下處理
if(file.exists()){
//如果不爲空刪除文件
file.delete();
}
//記錄已經下載的大小
int downLoadSize =0;
//記錄每次下載大小
int len = 0;
//每次下載多少字節
byte[] bytes = new byte[1024];
//創建文件輸出流管道
OutputStream os = new FileOutputStream(apkPash);
//開始下載文件
while ((len = is.read(bytes)) != -1){
//記錄每次下載的進度
downLoadSize += len;
os.write(bytes,0,len);
//處理進度條 拋出進度
publishProgress(downLoadSize*100 /contentLength);
}
os.close();
is.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}else{
return false;
}
}
/**
* 此方法執行在主線程中,在異步任務執行完後
* 一般用來操作結果
* @param b
*/
@Override
protected void onPostExecute(Boolean b) {
//更新UI
mButton.setText(b?"下載完成":"下載失敗");
mDwonLoadText.setText(b?"下載完成"+apkPash:"下載失敗");
}
/**
* 在執行過程中操作進度的改變
* @param values
*/
@Override
protected void onProgressUpdate(Integer... values) {
if(values !=null && values.length>0){
//接受進度
Integer value = values[0];
//更新進度條
mProgressBar.setProgress(value);
}
}
}
}
簡單封裝下步驟
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final int INIT_PROGRESS = 0;
private static final String APK_URL = "http://download.sj.qq.com/upload/connAssitantDownload/upload/MobileAssistant_1.apk";
private static final String APK_NAME = "aaaa.apk";
private ProgressBar mProgressBar;
private Button mButton;
private TextView mDwonLoadText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
initListener();
}
private void initView() {
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mButton = (Button)findViewById(R.id.button);
mDwonLoadText = (TextView)findViewById(R.id.tv_download);
}
private void initData() {
mProgressBar.setProgress(INIT_PROGRESS);//設置進度
mButton.setText(R.string.click_dwonload);
mDwonLoadText.setText(R.string.click_dwonload);
}
private void initListener() {
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//獲取文件存儲的路徑
final String apkPath = Environment.getExternalStorageDirectory()+File.separator+ APK_NAME +File.separator;
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DwonLoadHelper.dwonLoad(APK_URL, apkPath, new DwonLoadHelper.OnDownLoadListener() {
@Override
public void onStart() {
mButton.setText("正在下載");
mDwonLoadText.setText("正在下載");
}
@Override
public void onSuccess(int code, File file) {
mButton.setText("下載完成");
mDwonLoadText.setText("下載完成"+apkPath);
}
@Override
public void onFail(int code, File file, String message) {
Log.i(TAG,message);
}
@Override
public void onProgress(int progress) {
mProgressBar.setProgress(progress);
}
});
}
});
}
});
}
}
----------
----------
/**
* 對AsyncTask異步下載的簡單封裝
* 定義下載方法,傳入必要的url path listener參數 在AsyncTask裏進行回調
* 定義接口
*/
public class DwonLoadHelper {
public static void dwonLoad(String url ,String FilePath,OnDownLoadListener listener){
DwonloadAsyncTask dwonloadAsyncTask = new DwonloadAsyncTask(url,FilePath,listener);
dwonloadAsyncTask.execute();
}
static class DwonloadAsyncTask extends AsyncTask<String,Integer,Boolean> {
public String mUrl;
public String mFilePath;
public OnDownLoadListener mListener;
public DwonloadAsyncTask(String mUrl, String mFilePath, OnDownLoadListener mListener) {
this.mUrl = mUrl;
this.mFilePath = mFilePath;
this.mListener = mListener;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
if(mListener !=null){
mListener.onStart();
}
}
@Override
protected Boolean doInBackground(String... params) {
if(mListener!=null){
try {
//創建URL
URL url = new URL(mUrl);
//創建連接 並打開
URLConnection conn = url.openConnection();
//連接文件的總大小
int contentLength = conn.getContentLength();
//獲取文件的輸入流
InputStream is = conn.getInputStream();
File file = new File(mFilePath);
//對文件路徑做下處理
if(file.exists()){
//如果不爲空刪除文件
file.delete();
}
//記錄已經下載的大小
int downLoadSize =0;
//記錄每次下載大小
int len = 0;
//每次下載多少字節
byte[] bytes = new byte[1024];
//創建文件輸出流管道
OutputStream os = new FileOutputStream(mFilePath);
//開始下載文件
while ((len = is.read(bytes)) != -1){
//記錄每次下載的進度
downLoadSize += len;
os.write(bytes,0,len);
//處理進度條 拋出進度
publishProgress(downLoadSize*100 /contentLength);
}
os.close();
is.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}else{
mListener.onFail(-2,new File(mFilePath),"文件下載失敗");
return false;
}
}
/**
* 此方法執行在主線程中,在異步任務執行完後
* 一般用來操作結果
* @param b
*/
@Override
protected void onPostExecute(Boolean b) {
//更新UI
if(mListener !=null){
mListener.onSuccess(1,new File(mFilePath));
}else{
mListener.onFail(-1,new File(mFilePath),"文件下載失敗");
}
}
/**
* 在執行過程中操作進度的改變
* @param values
*/
@Override
protected void onProgressUpdate(Integer... values) {
if(values !=null && values.length>0){
//接受進度
Integer value = values[0];
if(mListener!=null){
mListener.onProgress(value);
}
}
}
}
/**
* 定義接口,定義必要的一些方法回調
*/
public interface OnDownLoadListener {
void onStart();
void onSuccess (int code ,File file);
void onFail(int code, File file, String message);
void onProgress(int progress);
//對接口簡單的小優化。有時候不需要用到那麼多方法,只定義幾個必須要用到的就可以了
//只用成功失敗的方法話,在接口調用時,用此類即可
abstract class SimpleDwonLoad implements OnDownLoadListener{
@Override
public void onSuccess(int code, File file) {
}
@Override
public void onFail(int code, File file, String message) {
}
}
}
}
對接口的回調和寫法有了一點了解,
可以把一些邏輯代碼封裝調用接口裏的方法處理結果,讓回調者在外面處理業務邏輯。