2010104第一行代碼第十章網(wǎng)絡(luò)

一稼稿、WebView

view=(WebView) findViewById(R.id.webView1);

view.setWebViewClient(new WebViewClient(){

@Override

public boolean shouldOverrideUrlLoading(WebView view, String url) {

// TODO Auto-generated method stub

view.loadUrl(url); ??//根據(jù)傳入的參數(shù)再去加載新的網(wǎng)頁

return true; ????????//表示當(dāng)前WebView可以處理打開新網(wǎng)頁的請求律胀,不用借助系統(tǒng)瀏覽器

}

});

view.loadUrl("http://www.baidu.com");

訪問網(wǎng)絡(luò)是需要聲明權(quán)限的:

二褒翰、使用HTTP協(xié)議訪問網(wǎng)絡(luò)

在Android中發(fā)送http請求有兩種方法:HttpURLConnection和HttpClient荤傲。

1耻涛、使用HttpURLConnection

首先呐伞,獲取訪問地址的URL敌卓;

然后,利用該url實例的openConnection()方法獲取HttpURLConnection實例伶氢;

之后趟径,利用HttpURLConnection實例,可以設(shè)置HTTP請求所使用的方法癣防,主要有兩種蜗巧,GET和POST,分別是請求數(shù)據(jù)和提交數(shù)據(jù)蕾盯;

之后幕屹,可以進(jìn)行一些自由的設(shè)置,比如設(shè)置連接超時時間级遭、請求超時時間等望拖;

最后,調(diào)用getInputStream()方法即可獲得服務(wù)器傳輸過來的輸入流了挫鸽∷得簦可以對該輸入流進(jìn)行讀取。

讀取完之后丢郊,需要關(guān)閉HTTP連接盔沫,調(diào)用disconnect()方法。

當(dāng)然枫匾,也需要在AndroidManifest.xml中注冊迅诬。

url = new URL("http://www.baidu.com");

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

connection.setRequestMethod("GET");

connection.setReadTimeout(8000);

connection.setConnectTimeout(8000);

InputStream inputStream=connection.getInputStream();

主程序如下:

public class MainActivity extends Activity {

Button send;

TextView textView;

public static final int REQUEST=0;

private Handler handler=new Handler()

{

public void handleMessage(Message msg) {

super.handleMessage(msg);

switch (msg.what) {

case REQUEST:

String responce=msg.obj.toString();

textView.setText(responce);

break;

default:

break;

}

}

};

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

send=(Button) findViewById(R.id.send);

textView=(TextView) findViewById(R.id.text);

send.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

SendRequest();

}

});

}

public void SendRequest()

{

//打開一個子線程用于請求網(wǎng)頁

new Thread(new Runnable() {

public void run() {

HttpURLConnection connection=null;

BufferedReader reader;

URL url;

try {

url = new URL("http://www.baidu.com");

connection=(HttpURLConnection) url.openConnection();

connection.setRequestMethod("GET");

connection.setReadTimeout(8000);

connection.setConnectTimeout(8000);

InputStream inputStream=connection.getInputStream();

InputStreamReader inputStreamReader=new InputStreamReader(inputStream);

reader=new BufferedReader(inputStreamReader);

StringBuilder builder=new StringBuilder();

String line="";

while((line=reader.readLine())!=null)

{

builder.append(line);

}

Message ?message=new Message();

message.what=REQUEST;

message.obj=builder;

handler.sendMessage(message);

} catch (Exception e) {

e.printStackTrace();

}

finally

{

if(connection!=null)connection.disconnect();

}

}

}).start();

}

…….

}

向服務(wù)器提交數(shù)據(jù):

首先,將HTTP請求方法改為POST婿牍;

然后侈贷,打開輸出流。

之后,將數(shù)據(jù)以鍵值對方式輸出俏蛮,數(shù)據(jù)之間用&隔開撑蚌。

connection.setRequestMethod("POST");

OutputStream outputStream=connection.getOutputStream();

DataOutputStream dataOutputStream=new DataOutputStream(outputStream);

dataOutputStream.writeBytes("username=hujun&password=123");

2、使用HttpClient

HttpClient是Apache提供的網(wǎng)絡(luò)訪問接口搏屑。

首先争涌,因為是接口,所以不能實例化辣恋,通常創(chuàng)建一個DefaultHttpClient的實例:

HttpClient httpClient = new DefaultHttpClient();

(1)GET請求

創(chuàng)建HttpGet對象亮垫,傳入目標(biāo)網(wǎng)絡(luò)地址,然后調(diào)用HttpClient的excute()方法伟骨。

HttpGet httpGet = new HttpGet(“http://www.baidu.com”);

httpClient.excute(httpGet);

(2)POST請求

首先饮潦,創(chuàng)建一個HttpPost對象,傳入網(wǎng)絡(luò)目標(biāo)地址携狭;

之后继蜡,用NameValuePair集合存放數(shù)據(jù);

之后逛腿,設(shè)置數(shù)據(jù)存放格式為utf-8稀并,利用UrlEncodeFormEntity轉(zhuǎn)碼;

之后单默,將轉(zhuǎn)碼后的entity放入HttpPost對象碘举;setEntity();

最后搁廓,調(diào)用httpClient的excute()方法即可引颈。

//創(chuàng)建HttpPost對象

HttpPost httpPost = new HttpPost(“http://www.baidu.com”);

//放入數(shù)據(jù)

List params = new ArrayList();

params.add(new BasicNameValuePair(“username”,”hujun” ));

params.add(new BasicNameValuePair(“password”,”123” ));

//轉(zhuǎn)碼

UrlEncodeFormEntity entity = new UrlEncodeFormEntity(params,”utf-8”);

httpPost.setEntity(entity);

//執(zhí)行

httpClient.excute(httpPost);

(3)服務(wù)器返回結(jié)果

執(zhí)行excute()之后,服務(wù)器會返回一個HttpResponse對象枚抵,該對象中包含所有的返回結(jié)果。

首先明场,取出服務(wù)器返回的狀態(tài)碼汽摹,如果狀態(tài)碼為200,說明響應(yīng)成功了苦锨。

HttpResponse httpResponse = httpClient.excute(httpGet/httpPost);

if(httpResponse.getStatusLine().getStatueCode()==200)

{

//執(zhí)行返回成功之后的代碼

}

之后逼泣,取出返回結(jié)果。先用getEntity()獲取HttpEntity實例舟舒,然后用EntityUtils.toString(entity,”utf-8”)將entity轉(zhuǎn)換為字符串拉庶。

public void SendClient()

{

new Thread(new Runnable() {

public void run() {

HttpClient httpClient = new DefaultHttpClient();

HttpPost httpPost = new HttpPost("http://www.baidu.com");

List params=new ArrayList();

params.add(new BasicNameValuePair("username", "hujun"));

params.add(new BasicNameValuePair("password", "123"));

try {

UrlEncodedFormEntity encodedFormEntity = new UrlEncodedFormEntity(params,"utf-8");

httpPost.setEntity(encodedFormEntity);

HttpResponse httpResponse = httpClient.execute(httpPost);

if(httpResponse.getStatusLine().getStatusCode()==200)

{

HttpEntity entity = httpResponse.getEntity();

String response = EntityUtils.toString(entity, "utf-8").toString();

Message message=new Message();

message.what=RESPONSE;

message.obj=response;

handler.sendMessage(message);

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}).start();

}

三、解析XML格式數(shù)據(jù)

首先秃励,需要建立一個xml文件用于解析氏仗。在www文件夾里建立get_data.xml

1

Google Maps

1.0

2

Chrome

2.1

3

Google Play

2.3

然后,利用Android程序去解析這段xml代碼夺鲜。

1皆尔、Pull解析方式

public void parseXMLwithPull(String response)

{

try {

XmlPullParserFactory factory=XmlPullParserFactory.newInstance();

XmlPullParser parser = factory.newPullParser();

parser.setInput(new StringReader(response));

int enventType=parser.getEventType();

while(enventType!=XmlPullParser.END_DOCUMENT)

{

String nodeName=parser.getName();

String id="";

String name="";

String version="";

switch (enventType) {

case XmlPullParser.START_TAG:

if("id".equals(nodeName))

{

id=parser.nextText();

}

else if("name".equals(nodeName))

{

name=parser.nextText();

}

else if("version".equals(nodeName))

{

version=parser.nextText();

}

break;

case XmlPullParser.END_TAG:

if("app".equals(nodeName))

{

Log.i("main", "id= "+id);

Log.i("main", "name= "+name);

Log.i("main", "version= "+version);

}

break;

default:

break;

}

enventType=parser.next();

}

} catch (Exception e) {

e.printStackTrace();

}

}

2呐舔、SAX解析方式

需要構(gòu)建一個自己的ContentHandler類去解析XML

public class ContentHandler extends DefaultHandler {

private StringBuilder id;

private StringBuilder name;

private StringBuilder version;

private String nodeName;

public void startDocument() throws SAXException {

super.startDocument();

id = new StringBuilder();

name = new StringBuilder();

version = new StringBuilder();

}

public void startElement(String uri, String localName, String qName,

Attributes attributes) throws SAXException {

super.startElement(uri, localName, qName, attributes);

//記錄當(dāng)前節(jié)點名

nodeName = localName;

}

public void characters(char[] ch, int start, int length)

throws SAXException {

super.characters(ch, start, length);

//根據(jù)當(dāng)前節(jié)點名,判斷將內(nèi)容放入哪個StringBuilder中

if("id".equals(nodeName))id.append(ch, start, length);

else if("name".equals(nodeName))name.append(ch, start, length);

else if("version".equals(nodeName))version.append(ch, start, length);

}

public void endElement(String uri, String localName, String qName)

throws SAXException {

super.endElement(uri, localName, qName);

if("app".equals(nodeName))

{

Log.i("ContentHandler", "id is "+id.toString().trim());

Log.i("ContentHandler", "name is "+name.toString().trim());

Log.i("ContentHandler", "version is "+version.toString().trim());

//最后需要將StringBuilder清空

id.setLength(0);

name.setLength(0);

version.setLength(0);

}

}

public void endDocument() throws SAXException {

super.endDocument();

}

}

在MainActivity.java中:

public void parseXMLWithSAX(String response)

{

try {

SAXParserFactory factory=SAXParserFactory.newInstance();

XMLReader xmlReader=factory.newSAXParser().getXMLReader();

ContentHandler handler=new ContentHandler();

xmlReader.setContentHandler(handler);

xmlReader.parse(new InputSource(new StringReader(response)));

} catch (Exception e) {

e.printStackTrace();

}

}

慷蠕、解析JSON格式數(shù)據(jù)

相比XML珊拼,JSON優(yōu)勢在于體積更小,在網(wǎng)絡(luò)上傳輸更省流量流炕。但缺點在于語義性較差澎现,不如XML直觀。

編輯get_data.json文件:

[{"id":"5","name":"hujun","version":"4.4"},

{"id":"6","name":"hujun6","version":"6.6"},

{"id":"7","name":"hujun7","version":"7.7"}]

解析JSON數(shù)據(jù)有很多方法每辟,比如官方提供的JSONObject剑辫,也可以使用Google的開源庫GSON。

1影兽、JSONObject

public void parseJSONWithJSONObject(String response)

{

try {

JSONArray jsonArray=new JSONArray(response);

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

JSONObject jsonObject=jsonArray.getJSONObject(i);

String id=jsonObject.getString("id");

String name=jsonObject.getString("name");

String version=jsonObject.getString("version");

Log.i("main", "id= "+id);

Log.i("main", "name= "+name);

Log.i("main", "version= "+version);

}

} catch (Exception e) {

e.printStackTrace();

}

}

private static final String JSON =

"wjr({\"id\":\"35\",\"list\":{\"wjr1\":{\"dengji\":\"2\",\"diming\":\"北京市\(zhòng)",\"daima\":\"110000000000\",\"zidi\":2},\"wjr2\":{\"dengji\":\"2\",\"diming\":\"天津市\(zhòng)",\"daima\":\"120000000000\",\"zidi\":2}}})";

String response=JSON;

response=response.substring(4);

JSONObject province=new JSONObject(response);

JSONObject list=province.getJSONObject("list");

for (int i = 1; i < list.length()+1; i++) {

Log.i("main", list.getJSONObject("wjr"+i).getString("diming"));

Log.i("main", list.getJSONObject("wjr"+i).getString("daima"));

}

2揭斧、GSON

首先需要一個Gsonjar包,放在lib中峻堰。

GSON可以將一段JSON格式的數(shù)據(jù)讹开,自動映射為一個對象。

比如一段JSON格式數(shù)據(jù)如下:

{"id":"5","name":"hujun","version":"4.4"}

利用GSON可以將上面的JSON格式直接映射為一個對象捐名。fromJson()接收兩個參數(shù):JSON數(shù)據(jù)和需要映射的類旦万。

Gson gson = new Gson();

Person person = gson.fromJson(jsonData,Person.class);

如果需要解析一段JSON數(shù)組,需要用TypeToken將期望解析的數(shù)據(jù)傳入到fromJson()中镶蹋。

成艘、網(wǎng)絡(luò)編程最佳實踐——java的回調(diào)機(jī)制

將通用的網(wǎng)絡(luò)操作提取到一個通用的類里,并提供一個靜態(tài)方法贺归。

但網(wǎng)絡(luò)操作是耗時操作淆两,因此需要將其放在一個子線程中進(jìn)行。

由于在子線程中進(jìn)行拂酣,在主程序中調(diào)用這個網(wǎng)絡(luò)操作類時秋冰,服務(wù)器還沒有來得及響應(yīng),這個方法就結(jié)束了婶熬,根本來不及返回數(shù)據(jù)剑勾。

因此,需要利用java的回調(diào)機(jī)制赵颅。

java的回調(diào)機(jī)制:

(1)首先虽另,需要定義一個接口;

public interface HttpCallBackListner {

void onFinish(String response);

void onError(Exception e);

}

onFinish()方法表示當(dāng)服務(wù)器成功響應(yīng)請求時調(diào)用饺谬,參數(shù)是服務(wù)器的響應(yīng)捂刺。

onError()表示網(wǎng)絡(luò)出現(xiàn)錯誤時調(diào)用,參數(shù)是錯誤信息。

(2)然后叠萍,將接口以參數(shù)形式芝发,放到網(wǎng)絡(luò)操作的通用類中;

public class HttpUtil {

public static void sendHttpRequest(final String address,final HttpCallBackListner listner)

{

new Thread(new Runnable() {

HttpURLConnection connection=null;

public void run() {

try {

URL url = new URL(address);

connection = (HttpURLConnection) url.openConnection();

connection.setRequestMethod("GET");

connection.setReadTimeout(8000);

connection.setConnectTimeout(8000);

connection.setDoInput(true);

connection.setDoOutput(true);

InputStream inputStream=connection.getInputStream();

InputStreamReader inputStreamReader=new InputStreamReader(inputStream);

BufferedReader bufferedReader=new BufferedReader(inputStreamReader);

StringBuilder builder=new StringBuilder();

String line="";

while((line=bufferedReader.readLine())!=null)

{

builder.append(line);

}

//讀取服務(wù)器響應(yīng)數(shù)據(jù)成功苛谷,則調(diào)用onFinish()方法

if(listner!=null)

{

listner.onFinish(builder.toString());

}

} catch (Exception e) {

//網(wǎng)絡(luò)服務(wù)發(fā)送錯誤辅鲸,調(diào)用onError()方法

if(listner!=null)

{

listner.onError(e);

}

}

finally

{

if(connection!=null)connection.disconnect();

}

}

}).start();

}

}

(3)最后,在調(diào)用sendHttpRequest()方法出腹殿,重寫HttpCallBackListener接口中的方法独悴。

HttpUtil.sendHttpRequest("http://www.baidu.com", new HttpCallBackListner() {

public void onFinish(String response) {

//在這里處理服務(wù)器返回的結(jié)果

}

public void onError(Exception e) {

//在這里處理網(wǎng)絡(luò)出錯

}

});

這樣就可以利用回調(diào)機(jī)制,將響應(yīng)數(shù)據(jù)成功的返回給調(diào)用方了锣尉。需要注意刻炒,onFinish()和onError()方法都是在子線程中運(yùn)行的,因此不能在其中執(zhí)行UI操作自沧,需要用Handler的sendMessage異步處理機(jī)制坟奥。

?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市拇厢,隨后出現(xiàn)的幾起案子爱谁,更是在濱河造成了極大的恐慌,老刑警劉巖孝偎,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件访敌,死亡現(xiàn)場離奇詭異,居然都是意外死亡衣盾,警方通過查閱死者的電腦和手機(jī)寺旺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來势决,“玉大人阻塑,你說我怎么就攤上這事」矗” “怎么了陈莽?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長据悔。 經(jīng)常有香客問我传透,道長耘沼,這世上最難降的妖魔是什么极颓? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮群嗤,結(jié)果婚禮上菠隆,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好骇径,可當(dāng)我...
    茶點故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布躯肌。 她就那樣靜靜地躺著,像睡著了一般破衔。 火紅的嫁衣襯著肌膚如雪清女。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天晰筛,我揣著相機(jī)與錄音嫡丙,去河邊找鬼。 笑死读第,一個胖子當(dāng)著我的面吹牛曙博,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播怜瞒,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼父泳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吴汪?” 一聲冷哼從身側(cè)響起惠窄,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎浇坐,沒想到半個月后睬捶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡近刘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年擒贸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片觉渴。...
    茶點故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡介劫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出案淋,到底是詐尸還是另有隱情座韵,我是刑警寧澤,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布踢京,位于F島的核電站誉碴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏瓣距。R本人自食惡果不足惜黔帕,卻給世界環(huán)境...
    茶點故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹈丸。 院中可真熱鬧成黄,春花似錦呐芥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至闻伶,卻和暖如春滨攻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蓝翰。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工铡买, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人霎箍。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓奇钞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親漂坏。 傳聞我的和親對象是個殘疾皇子景埃,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,442評論 2 359

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)顶别,斷路器谷徙,智...
    卡卡羅2017閱讀 134,693評論 18 139
  • apache下的httpclient工具可大大簡化開發(fā)過程中的點對點通信,本人將以微信多媒體接口為例驯绎,展示http...
    劃破的天空閱讀 5,301評論 0 32
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法完慧,類相關(guān)的語法,內(nèi)部類的語法剩失,繼承相關(guān)的語法屈尼,異常的語法,線程的語...
    子非魚_t_閱讀 31,660評論 18 399
  • 1拴孤、不安全的隨機(jī)數(shù)生成脾歧,在CSRF TOKEN生成、password reset token生成等演熟,會造成toke...
    nightmare丿閱讀 3,705評論 0 1
  • Wamp localhost/127.0.0.1 步驟 服務(wù)器工具:http://www.php100.com/h...
    Stago閱讀 152評論 0 0