用接口回调的方法实现异步请求网络数据
注意:请求网络需要添加网络权限
<uses-permission android:name="android.permission.INTERNET"/>
此demo中使用了接口回调、异步加载、HttpURLConnection请求
//---------------定义一个接口------------------------------
public interface WeatherFace {
//定义一个接口,一个成功和一个异常的方法
public void succeed(String str);
public void error(Exception str);
}
//------------------定义一个类请求网络数据-------------------------
package com.example.yibu;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import android.os.AsyncTask;
public class Weather {
/**
* 定义getWeather方法获得网络请求(参数一:http路径,参数二:自己定义的接口)
* @param url
* @param weatherFace
*/
public void getWeather(String url,final WeatherFace weatherFace){
//使用异步加载数据
new AsyncTask<String, Void, String>(){
/**
* doInBackground 方法相当于子线程,用于耗时操作
*/
@Override
protected String doInBackground(String... params) {
try {
// 使用 HttpURLConnection请求网络数据
URL url=new URL(params[0]);
HttpURLConnection urlConnection=(HttpURLConnection) url.openConnection();
urlConnection.setConnectTimeout(5000);
urlConnection.setReadTimeout(5000);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
int code=urlConnection.getResponseCode();
if (code==200) {
InputStream inputStream=urlConnection.getInputStream();
BufferedReader reader=new BufferedReader(new InputStreamReader(inputStream));
String readerline;
StringBuffer buffer=new StringBuffer();
while ((readerline=reader.readLine())!=null) {
buffer.append(readerline);
}
String str=buffer.toString();
//把请求到的数据返给 onPostExecute
return str;
}
} catch (IOException e) {
/**
* 调用接口,返回请求异常的结果,这里是在子线程中做的,所以不懂直接更新UI
*/
weatherFace.error(e);
e.printStackTrace();
}
return null;
}
/**
* 此方法用于更新UI
*/
protected void onPostExecute(String result) {
//调用接口,返回请求成功的数据
weatherFace.succeed(result);
};
//此地方是请求的地址
}.execute(url);
}
}
//----------------MainActivity中,实现接口------------------------------
package com.example.yibu;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private TextView tv_text;
private Button bt_button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到控件
tv_text = (TextView) findViewById(R.id.tv_text);
bt_button = (Button) findViewById(R.id.bt_button);
//设置按钮的监听
bt_button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//按钮
case R.id.bt_button:
//创建天气类
Weather weather=new Weather();
//调用天气类中的获得天气的方法(并实现接口中的方法)
weather.getWeather("htp://api.map.baidu.com/telematics/v3/weather?location=beijing&output=json&ak=GuZriL3rkm1MUnyTyfsNGvTC", new WeatherFace() {
@Override //成功
public void succeed(String str) {
tv_text.setText(str);
}
@Override //异常
public void error(final Exception str) {
//此方法是因为不能在子线程中更新UI ,因为抛出的异常实在子线程中的,而上面succeed方法中是在异步的
runOnUiThread(new Runnable() {
public void run() {
tv_text.setText(str.toString());
Log.i("hhhhh", str.toString());
Toast.makeText(MainActivity.this, str.toString(), 0).show();
}
});
}
});
break;
default:
break;
}
}
}
//---------------xml文件----------------------
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv_text" />
<Button android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="点击请求数据"
android:id="@+id/bt_button"/>
</LinearLayout>