day04 網(wǎng)絡(luò)編程

1.寫一個網(wǎng)絡(luò)源碼查看器

思路:

1.寫布局 EditText Button TextView ok

2.找控件饮六,設(shè)置點擊事件 ok

3.在點擊事件的onclick中浅萧,獲取用戶輸入的url ok

4.訪問url,獲取源碼 ********* 不ok

//4.1 創(chuàng)建一個URL對象;

URL url = new URL(url_str);

//4.2 通過url對象獲取一個HttpUrlConnection對象

HttpURLConnection cn = (HttpURLConnection) url.openConnection();

//4.3 為HttpUrlConnection對象設(shè)置一些參數(shù) . 如:網(wǎng)絡(luò)請求方式 路捧,連接的超時時間

cn.setRequestMethod("GET");//設(shè)置網(wǎng)絡(luò)的請求方式 GET ,POST一定 要大寫

cn.setConnectTimeout(10*1000);//設(shè)置網(wǎng)絡(luò)連接的超時時間

//4.4 獲取網(wǎng)絡(luò)的響應(yīng)狀態(tài)碼

int code = cn.getResponseCode();//獲取服務(wù)器的響應(yīng)碼

//4.5判斷狀態(tài)碼是否是200慢显,如果是200 獲取流數(shù)據(jù)

if(code == 200){

InputStream inputStream = cn.getInputStream();//獲取一個讀取流讀取服務(wù)器返回的數(shù)據(jù)

//4.6 將獲取的流數(shù)據(jù)轉(zhuǎn)換成字符串持际,就是我們所需的源碼

String result = Utils.StreamToString(inputStream);

//5.將源碼顯示到TextView上

tv_source.setText(result);

}

5.將源碼顯示到TextView上

2.出現(xiàn)的問題

1.注意添加網(wǎng)絡(luò)訪問權(quán)限:

2.ANR: 多次點擊按鈕會出現(xiàn)application not response應(yīng)用無響應(yīng)的異常;

安卓規(guī)定耗時的操作(網(wǎng)絡(luò)請求,大文件的拷貝殴蹄,數(shù)據(jù)庫的操作)需要放到子線程中執(zhí)行究抓,不能在主線程中執(zhí)行.4.0以后android強制要求網(wǎng)絡(luò)請求必須放到子線程中執(zhí)行,android4.0之后會報錯誤:NetworkOnMainThreadException袭灯;

11-01 02:44:12.618: E/ActivityManager(858): ANR in com.itheima.sourcelook (com.itheima.sourcelook/.MainActivity)

3.NetworkOnMainThreadException 網(wǎng)絡(luò)訪問在主線程異常

11-01 02:47:40.231: W/System.err(1806): android.os.NetworkOnMainThreadException

4.當(dāng)創(chuàng)建了子線程并將操作放入子線程之后會報CalledFromWrongThreadException 錯誤的線程調(diào)用異常 ,只有主線程才能夠更新UI刺下,子線程不能更新UI(改變控件的內(nèi)容或樣式)。

11-01 02:56:07.750: W/System.err(1947): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

結(jié)論:耗時的操作需要放到子線程中執(zhí)行稽荧,不能在主線程中執(zhí)行橘茉;只有主線程才能更新UI,子線程獲取到數(shù)據(jù)不能直接更新UI.產(chǎn)生了矛盾姨丈。畅卓。如何解決? Handler

3.handler消息機制

思路:

1.在主線程創(chuàng)建一個Handler對象蟋恬,成員變量翁潘。

new Handler()

2.重新handler對象的handlerMessage方法

new Handler(){

handlerMessage(Message msg){

}

}

3.在子線程中創(chuàng)建一個Message對象。

Message msg = new Message();

4.將子線程獲取的結(jié)果綁定給Message對象

msg.obj = result;

5.子線程中使用主線程創(chuàng)建的handler將Message對象發(fā)送到主線程

handler.sendMessage(msg);

6.主線程中的handler對象的handlerMessage方法接受子線程發(fā)來的Message對象歼争,可以獲取Message對象中綁定的數(shù)據(jù)拜马,做UI更新

new Handler(){

handlerMessage(Message msg){

String result = msg.obj;

textview.setText(result);

}

}

4.網(wǎng)絡(luò)圖片查看器

BitmapFactory 可以將各種各樣的資源(文件渗勘,流,二進(jìn)制數(shù)組)轉(zhuǎn)換成一個Bitmap對象俩莽。

Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

代碼:

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//2.找控件旺坠,寫點擊事件

et_url = (EditText) findViewById(R.id.et_url);

img_pic = (ImageView) findViewById(R.id.img_pic);

findViewById(R.id.bt_getpic).setOnClickListener(this);

System.out.println("oncreate:"+Thread.currentThread().getName());

}

//☆☆☆☆☆? 1.在主線程中創(chuàng)建一個Handler對象

privateHandler handler =newHandler(){

//☆☆☆☆☆? 2.復(fù)寫Handler對象的一個handlerMessage方法

publicvoidhandleMessage(android.os.Message msg) {

//☆☆☆☆☆? 6.在主線程的handler對象中的handleMessage方法接受子線程發(fā)來的Message對象,并獲取綁定的數(shù)據(jù)豹绪;那么主線程就可以更新UI了价淌。

Bitmap bm? = (Bitmap) msg.obj;

// 當(dāng)前線程為主線程,可以更新Ui

//5.將bitmap設(shè)置給Imageview做展示

img_pic.setImageBitmap(bm);

};

};

@Override

publicvoidonClick(View v) {

//創(chuàng)建一個子線程

newThread(newRunnable() {

@Override

publicvoidrun() {

System.out.println("runnable:"+Thread.currentThread().getName());

//3.在點擊事件的onclick中瞒津,獲取用戶輸入的url? ok

String url_str = et_url.getText().toString().trim();

try{

//4.訪問url,獲取源碼????????????? ********* 不ok

//4.1 創(chuàng)建一個URL對象蝉衣;

URL url =newURL(url_str);

//4.2 通過url對象獲取一個HttpUrlConnection對象

HttpURLConnection cn = (HttpURLConnection) url.openConnection();

//4.3? 為HttpUrlConnection對象設(shè)置一些參數(shù) .?? 如:網(wǎng)絡(luò)請求方式 ,連接的超時時間

cn.setRequestMethod("GET");//設(shè)置網(wǎng)絡(luò)的請求方式 GET ,POST一定 要大寫

cn.setConnectTimeout(10*1000);//設(shè)置網(wǎng)絡(luò)連接的超時時間

//4.4 獲取網(wǎng)絡(luò)的響應(yīng)狀態(tài)碼

intcode = cn.getResponseCode();//獲取服務(wù)器的響應(yīng)碼

//4.5判斷狀態(tài)碼是否是200巷蚪,如果是200 獲取流數(shù)據(jù)

if(code == 200){

InputStream inputStream = cn.getInputStream();//獲取一個讀取流讀取服務(wù)器返回的數(shù)據(jù)

//4.6 將獲取的流數(shù)據(jù)轉(zhuǎn)換成圖片資源?? Drawable Bitmap:位圖

//使用BitmapFactory將各種資源(流病毡,文件,二進(jìn)制數(shù)組)轉(zhuǎn)換成圖片對象Bitmap

Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

//☆☆☆☆☆? 3.在子線程中創(chuàng)建一個Message對象

Message msg =newMessage();

//☆☆☆☆☆? 4.將子線程中獲取的數(shù)據(jù)綁定給Message對象

msg.obj = bitmap;

//☆☆☆☆☆? 5.使用主線程中的handler對象將綁定數(shù)據(jù)的Message對象發(fā)送到主線程

handler.sendMessage(msg);

}

}catch(Exception e) {

e.printStackTrace();

}

}

}).start();

}

5.設(shè)計自己的SmartImageView控件(可以通過URI設(shè)置控件顯示的圖片)

思路:

1.通過httpurlconnection連接網(wǎng)絡(luò)資源

2.通過bitmapfactory獲得bitmap(factory可以通過流轉(zhuǎn)換bitmap)

3.建立message

4.用handler傳遞message獲得bitmap

5.在自己的控件中顯示

注意:

自定義控件:

1.寫一個類繼承ImageView,寫三個構(gòu)造方法

2.寫一個setImageUrl方法屁柏,請求url地址啦膜,獲取圖片流,轉(zhuǎn)換成bitmap,設(shè)置給當(dāng)前類的對象淌喻。

3.在布局文件中引用自定義的MySmartImageView ,注意僧家,引用時,需要指定類的完整路徑裸删。

代碼

publicclassMySmartImageViewextendsImageView{

Handlerhand=newHandler(){

publicvoidhandleMessage(Message msg) {

Bitmap img=(Bitmap) msg.obj;

//自定義控件標(biāo)簽要寫全包名

//

//android:layout_height="68dp"

//android:layout_width="68dp"

//android:layout_margin="10dp"

//android:id="@+id/iv_view"

//android:src="@drawable/ic_launcher"/>

MySmartImageView.this.setImageBitmap(img);

};

};

//一定要復(fù)寫3個方法八拱,否則運行會報錯

publicMySmartImageView(Context context, AttributeSet attrs,intdefStyle) {

super(context, attrs, defStyle);

//TODOAuto-generated constructor stub

}

publicMySmartImageView(Context context, AttributeSet attrs) {

super(context, attrs);

//TODOAuto-generated constructor stub

}

publicMySmartImageView(Context context) {

super(context);

//TODOAuto-generated constructor stub

}

publicvoidSetImageUrl(String url)

{

finalString url2=url;

newThread(newRunnable() {

@Override

publicvoidrun() {

try{

URL url1=newURL(url2);

HttpURLConnection con=(HttpURLConnection) url1.openConnection();

con.setReadTimeout(10000);

con.setRequestMethod("GET");

if(con.getResponseCode()==200)

{

InputStream in=con.getInputStream();

Bitmap img=BitmapFactory.decodeStream(in);

Message msg=newMessage();

msg.obj=img;

hand.sendMessage(msg);

}

}catch(MalformedURLException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(IOException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

//TODOAuto-generated method stub

}

}).start();

}

}

6.常見消息處理API

1.子線程可以更新UI的情況

//面試:: 審計機制 ,在activity完全顯示之后才會工作涯塔,才會檢測是否在子線程中更新UI肌稻,顯示之前更新UI審計機制不會工作。

// 還有一些情況可以在子線程更新Ui匕荸,如SurfaceView和與進(jìn)度條相關(guān)的控件都可以在子線程更新UI爹谭。

代碼:

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

tv_text= (TextView)findViewById(R.id.tv_text);

//SystemClock.sleep(5000);

newThread(newRunnable() {

publicvoidrun() {

SystemClock.sleep(5000);

tv_text.setText("我被更新了");

}

}).start();

}

2.runOnUiThread方法:無論當(dāng)前線程是否是主線程,都會被在主線程中執(zhí)行

//在activity中有一個runOnUIthread方法,UI線程就是主線程無論要運行的動作是否是主線程榛搔,都將會在主線程運行诺凡。

runOnUiThread(new Runnable() {

@Override

public void run() {

tv_simple.setText("我被更新了");

}

});

3.handler 的post方法

//使用handler 的post方法將一個動作發(fā)送到主線程去執(zhí)行。 這個handler必須定義在主線程

handler.post(new Runnable() {

@Override

public void run() {

tv_simple.setText("我被更新了");

}

});

4.handler 的postDelaed方法践惑,發(fā)送一個延遲的動作到主線程绑洛,特別適合做廣告展示。

//delayMillis:延遲的時間

handler.postDelayed(new Runnable() {

@Override

public void run() {

tv_simple.setText("我被更新了");

}

}, 5000);

7.android的Json解析

1.android自帶Json封裝API

String result = Utils.StreamToString(inputStream);//獲得一個Json字符串

//6.解析json字符串童本,封裝到list中

JSONObject root_json = new JSONObject(result);//將一個json字符串轉(zhuǎn)換成一個jsonObject

//根據(jù)json的key獲取newss這個json數(shù)組

JSONArray jsonArray = root_json.getJSONArray("newss");

//遍歷jsonArray獲取一條條json數(shù)據(jù)

for (int i = 0; i < jsonArray.length(); i++) {

JSONObject newsJson = jsonArray.getJSONObject(i);//根據(jù)索引獲取數(shù)組中的一個json對象

NewsBean bean = new NewsBean();

bean.id = newsJson.getInt("id");

bean.comment = newsJson.getInt("comment");

bean.type = newsJson.getInt("type");

bean.title = ???? newsJson.getString("title");

bean.des = ???? newsJson.getString("des");

bean.icon_url = newsJson.getString("icon_url");

bean.news_url = newsJson.getString("news_url");

bean.time = newsJson.getString("time");

arrayList.add(bean);

2.第三方工具包解析介紹(最好選擇Gson)

1.、各個JSON技術(shù)的簡介和優(yōu)劣

1.json-lib

json-lib最開始的也是應(yīng)用最廣泛的json解析工具脸候,json-lib 不好的地方確實是依賴于很多第三方包穷娱,

包括commons-beanutils.jar绑蔫,commons-collections-3.2.jar,commons-lang-2.6.jar泵额,commons-logging-1.1.1.jar配深,ezmorph-1.0.6.jar,

對于復(fù)雜類型的轉(zhuǎn)換嫁盲,json-lib對于json轉(zhuǎn)換成bean還有缺陷篓叶,比如一個類里面會出現(xiàn)另一個類的list或者map集合,json-lib從json到bean的轉(zhuǎn)換就會出現(xiàn)問題羞秤。

json-lib在功能和性能上面都不能滿足現(xiàn)在互聯(lián)網(wǎng)化的需求缸托。

2.開源的Jackson

相比json-lib框架,Jackson所依賴的jar包較少瘾蛋,簡單易用并且性能也要相對高些俐镐。

而且Jackson社區(qū)相對比較活躍,更新速度也比較快哺哼。

Jackson對于復(fù)雜類型的json轉(zhuǎn)換bean會出現(xiàn)問題佩抹,一些集合Map,List的轉(zhuǎn)換出現(xiàn)問題取董。

Jackson對于復(fù)雜類型的bean轉(zhuǎn)換Json棍苹,轉(zhuǎn)換的json格式不是標(biāo)準(zhǔn)的Json格式

3.Google的Gson

Gson是目前功能最全的Json解析神器,Gson當(dāng)初是為因應(yīng)Google公司內(nèi)部需求而由Google自行研發(fā)而來茵汰,

但自從在2008年五月公開發(fā)布第一版后已被許多公司或用戶應(yīng)用枢里。

Gson的應(yīng)用主要為toJson與fromJson兩個轉(zhuǎn)換函數(shù),無依賴经窖,不需要例外額外的jar坡垫,能夠直接跑在JDK上。

而在使用這種對象轉(zhuǎn)換之前需先創(chuàng)建好對象的類型以及其成員才能成功的將JSON字符串成功轉(zhuǎn)換成相對應(yīng)的對象。

類里面只要有g(shù)et和set方法闺魏,Gson完全可以將復(fù)雜類型的json到bean或bean到j(luò)son的轉(zhuǎn)換操灿,是JSON解析的神器。

Gson在功能上面無可挑剔溉卓,但是性能上面比FastJson有所差距。

4.阿里巴巴的FastJson

Fastjson是一個Java語言編寫的高性能的JSON處理器,由阿里巴巴公司開發(fā)搬泥。

無依賴桑寨,不需要例外額外的jar,能夠直接跑在JDK上忿檩。

FastJson在復(fù)雜類型的Bean轉(zhuǎn)換Json上會出現(xiàn)一些問題尉尾,可能會出現(xiàn)引用的類型,導(dǎo)致Json轉(zhuǎn)換出錯燥透,需要制定引用沙咏。

FastJson采用獨創(chuàng)的算法辨图,將parse的速度提升到極致,超過所有json庫肢藐。

綜上4種Json技術(shù)的比較故河,在項目選型的時候可以使用Google的Gson和阿里巴巴的FastJson兩種并行使用,

如果只是功能要求吆豹,沒有性能要求鱼的,可以使用google的Gson,

如果有性能上面的要求可以使用Gson將bean轉(zhuǎn)換json確保數(shù)據(jù)的正確痘煤,使用FastJson將Json轉(zhuǎn)換Bean

Gson解析:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凑阶,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子速勇,更是在濱河造成了極大的恐慌晌砾,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烦磁,死亡現(xiàn)場離奇詭異养匈,居然都是意外死亡,警方通過查閱死者的電腦和手機都伪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進(jìn)店門呕乎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人陨晶,你說我怎么就攤上這事猬仁。” “怎么了先誉?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵湿刽,是天一觀的道長。 經(jīng)常有香客問我褐耳,道長诈闺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任铃芦,我火速辦了婚禮雅镊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘刃滓。我一直安慰自己仁烹,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布咧虎。 她就那樣靜靜地躺著卓缰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上征唬,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天震叮,我揣著相機與錄音,去河邊找鬼鳍鸵。 笑死,一個胖子當(dāng)著我的面吹牛尉间,可吹牛的內(nèi)容都是我干的偿乖。 我是一名探鬼主播,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼哲嘲,長吁一口氣:“原來是場噩夢啊……” “哼贪薪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起眠副,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤画切,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后囱怕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體霍弹,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年娃弓,在試婚紗的時候發(fā)現(xiàn)自己被綠了典格。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡台丛,死狀恐怖耍缴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情挽霉,我是刑警寧澤防嗡,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站侠坎,受9級特大地震影響蚁趁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜硅蹦,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一荣德、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧童芹,春花似錦涮瞻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春宁否,著一層夾襖步出監(jiān)牢的瞬間窒升,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工慕匠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留饱须,地道東北人。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓台谊,卻偏偏與公主長得像蓉媳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子锅铅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容