android AsynTask處理返回數據和AsynTask使用get,post請求
Android是一個單線程模型,Android界面(UI)的繪制都只能在主線程中進行,如果在主線程中進行耗時的操作,就會影響UI的繪制和事件的響應。所以在android規(guī)定,不可在主線中進行耗時操作,否則將發(fā)生程序無響應(ANR)問題。
解決辦法:開啟新的線程進行耗時操作
開啟新的線程可以new Thread() 或實現(xiàn)Runnable接口
什么要使用AsyncTask呢?
如果是使用Thread的run()方法,run()結束之后沒有返回值。所以必須要自己建立通信機制
AsyncTask將所有的線程通信都封裝成回調函數,調用邏輯容易書寫。尤其是在異步處理結束之后,有回調函數進行收尾處理。咳咳,程序員都懶的么
Android給我們提供的一個輕量級的用于處理異步任務的類:AsyncTask 當然是那個簡單就用那個咯
最后還有一點就是:Android 4.0后禁止在UI線程中執(zhí)行網絡操作~不然會報:android.os.NetworkOnMainThreadException
什么是AsyncTask(原諒寶寶偷的圖 嘿嘿 不過真的解釋的很清楚呢)


注意:
Task的實例必須在UI Thread中創(chuàng)建
execute方法不惜在UI thread中創(chuàng)建
task只能被執(zhí)行一次 多次調用時會出現(xiàn)異常
通用AsyncTask 以及在主線程中使用網絡請求回返的數據
通用AsyncTask是什么意思呢 發(fā)送不同的請求返回不同類型的數據 難道要一個類型寫個AsyncTask 豈不是麻煩死咯
還有一種情況 我們通過異步任務得到了一個對象然后在一下行立刻使用這個對象邏輯完全沒問題但是運行之后會報空指針異常。這是怎么回事呢?
AsycnTask開始了一個新的線程,但是主線程并沒有停止還在繼續(xù)運行,馬上就使用這個對象,而你新開的線程可能正在訪問網絡這個對象為空
你無法確定AsycnTask什么時候才能獲取到數據,網快嗖的一下就好了,網慢就要等好久。
看一個簡略的小例子
首先呢 我們使用異步任務的時候要處理不同類型的數據把這個Http設置泛型類第三個參數返回值類型設置為泛型不管你是什么類型的數據全部ok
我又寫了一個接口作為Http的屬性 在onPostExecute方法調用其中的onResponse方法在Test中實現(xiàn)接口
這個接口的作用完全可以理解為一個監(jiān)聽事件 checkbox的改變監(jiān)聽觸發(fā)條件是 是否選中這個接口監(jiān)聽是否有數據 完成網絡訪問有數據的時候就調用
我們在主線程中完成接口的實現(xiàn)已經在主線程中實現(xiàn)了返回來的數據還不是任君宰割阿~~~~~
public class Http<T> extends AsyncTask<String,Void,T> {
private OnResponseListener<T> listener;
public void setListener(OnResponseListener<T> listener) {
this.listener = listener;
}
@Override
protected T doInBackground(String... params) {
return null;
}
@Override
protected void onPostExecute(T t) {
super.onPostExecute(t);
if (listener!=null){
listener.onResponse(t);
}
}
//接口 類似一個監(jiān)聽事件
public interface OnResponseListener<T>{
void onResponse(T t);
}
}
//獲取數據的測試類
public class Test {
//要獲取的user對象
private User user1=null;
public void get(){
//創(chuàng)建網絡訪問實例
Http<User> http=new Http<User>();
//重寫接口
http.setListener(new Http.OnResponseListener<User>() {
@Override
public void onResponse(User user) {
user1=user;
}
});
http.execute("xxx.balabala.com");
}
}
在發(fā)送請求的時候很容易就帶個參數,請求的方式呢 無非就是get,post 兩者的區(qū)別呢大白話的說get不安全參數通過url直接傳過去post安全參數加密一下子
下面貼一下AsyncTask在get和post請求時核心代碼doInBackground方法
GET
protected T doInBackground(String... params) {
//網絡連接對象
HttpURLConnection connection=null;
//輸入流 獲取網絡數據
InputStream is=null;
//字節(jié)數組輸出流
ByteArrayOutputStream bos=null;
try {
//獲取網絡連接對象
connection=(HttpURLConnection) new URL(params[0]).openConnection();
//設置get請求 必須大寫
connection.setRequestMethod("GET");
//獲取網絡請求碼 200 400 500之類 不懂百度
int code=connection.getResponseCode();
if(code==200){
//獲取流
is=connection.getInputStream();
//臨時字節(jié)數組
byte [] b=new byte[1024];
int len=-1;
bos=new ByteArrayOutputStream();
while ((len=is.read(b))!=-1){
//寫入數據
bos.write(b,0,len);
}
String json=bos.toString("utf-8");
T t=JSON.parseObject(json,type);
return t;
}else{
Log.e("error","網絡訪問失敗==========="+code);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (bos!=null){
bos.close();
}
if (is!=null){
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (connection!=null){
connection.disconnect();
}
}
return null;
}
POST
post和get的區(qū)別 就是post多了一段處理參數的代碼
protected T doInBackground(String... params) {
//分割url 分為地址和參數兩部分
String[] strArr=params[0].split("\\?");
HttpURLConnection connection=null;
//輸出流
OutputStream os=null;
//輸入流
InputStream is=null;
ByteArrayOutputStream bos=null;
try {
connection=(HttpURLConnection) new URL(strArr[0]).openConnection();
connection.setRequestMethod("POST");
//設置允許輸入 輸出 默認值true 不寫也可以
connection.setDoOutput(true);
connection.setDoInput(true);
os=connection.getOutputStream();
//把參數寫入
os.write(strArr[1].getBytes("utf-8"));
os.close();
int code=connection.getResponseCode();
if(code==200){
is=connection.getInputStream();
byte [] b=new byte[1024];
int len=-1;
bos=new ByteArrayOutputStream();
while ((len=is.read(b))!=-1){
bos.write(b,0,len);
}
String json=bos.toString("utf-8");
T t=JSON.parseObject(json,type);
return t;
}else{
Log.e("error","網絡訪問失敗==========="+code);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (bos!=null){
bos.close();
}
if (is!=null){
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (connection!=null){
connection.disconnect();
}
}
return null;
}
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
- 詳解Android:向服務器提供數據之get、post方式
- Android中post和get的提交方式【三種】
- Android中使用OkHttp包處理HTTP的get和post請求的方法
- Android中使用HttpURLConnection實現(xiàn)GET POST JSON數據與下載圖片
- android平臺HttpGet、HttpPost請求實例
- android使用url connection示例(get和post數據獲取返回數據)
- Android發(fā)送GET與POST請求的DEMO詳解
- android之HttpPost&HttpGet使用方法介紹
- Android HttpClient GET或者POST請求基本使用方法
- 安卓GET與POST網絡請求的三種方式
相關文章
android開發(fā)教程之實現(xiàn)listview下拉刷新和上拉刷新效果
這篇文章主要介紹了android實現(xiàn)listview下拉刷新和上拉刷新效果,Android的ListView上拉下拉刷新,原理都一樣,在Touch事件中操作header/footer的paddingTop屬性,需要的朋友可以參考下2014-02-02
Android開發(fā)基于ScrollView實現(xiàn)的漸變導航欄效果示例
這篇文章主要介紹了Android開發(fā)基于ScrollView實現(xiàn)的漸變導航欄效果,涉及ScrollView事件響應及元素屬性動態(tài)操作相關實現(xiàn)技巧,需要的朋友可以參考下2017-12-12
Android中fragment嵌套fragment問題解決方法
這篇文章主要介紹了Android中fragment嵌套fragment問題解決方法,本文給出兩個解決方法,需要的朋友可以參考下2015-06-06
Android之利用EventBus發(fā)送消息傳遞示例
本篇文章主要介紹了Android之利用EventBus進行消息傳遞示例。EventBus是一款針對Android優(yōu)化的發(fā)布/訂閱事件總線,非常具有實用價值,需要的朋友可以參考下。2017-02-02
Android ListView 單條刷新方法實踐及原理解析
這篇文章主要介紹了Android ListView 單條刷新方法實踐及原理解析的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-07-07
Android recycleView的應用和點擊事件實例詳解
這篇文章主要介紹了Android recycleView的應用和點擊事件實例詳解的相關資料,需要的朋友可以參考下2016-12-12
Android仿QQ在狀態(tài)欄顯示登錄狀態(tài)效果
這篇文章主要介紹了Android仿QQ在狀態(tài)欄顯示登錄狀態(tài)效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12

