Android访问网络HttpURLConnection OkHttp 封装
Android中常用的应用都会大量使用网络,比如QQ、微信、访问网页等等。通过使用网络,可以展示网页,发起Http请求获取数据或提交数据。
WebView
控件
有时我们可能需要让我们自己的应用展示网页,我们可以使用Android内置的控件WebView
。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webView = (WebView)findViewById(R.id.web_view);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("http://www.baidu.com");
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
由于使用了网络功能,需要声明网络权限。在AndroidManifest.xml
添加android.permission.INTERNET
:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jyoryo.app.android.study">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Android主线程、子线程
- 主线程,不允许在主线程中进行网络请求,如果需要发起网络请求,方法是开启一个线程,然后在子线程里使用
HttpURLConnection
发起HTTP请求。例如下面使用HttpURLConnection
发起HTTP请求。 - 子线程,不允许在子线程中进行UI操作,如果需要进行UI操作必须切换到主线程中。可以使用
runOnUiThread()
方法将线程切换到主线程。
使用runOnUiThread()
:
private void showResponse(final String response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
responseText.setText(response);
}
});
}
HttpURLConnection
HttpURLConnection
是jdk自带的访问网络方式。
private void sendRequestWithHttpURLConnection(final String strUrl) {
new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "run: start http request");
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(strUrl);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
InputStream in = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder sbd = new StringBuilder();
String line = null;
while (null != (line = reader.readLine())) {
sbd.append(line);
}
showResponse(sbd.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(null != reader) {
reader.close();
}
if(null != connection) {
connection.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
如果使用POST
方式,比如提交用户名、密码:
connection.setRequestMethod("POST");
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("username=user&password=123");
OkHttp
通过HttpURLConnection
可以完成网络请求,但是比较原始,我们可以通过使用OkHttp
更便捷的完成网络请求。
private void sendRequestWithOkHttp(final String url) {
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
try {
Response response = client.newCall(request).execute();
String responseData = response.body().string();
showResponse(responseData);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
网络请求封装
HttpUtil
网络请求封装类:
public class HttpUtil {
public interface HttpCallbackListener {
void onFinish(String response);
void onError(Exception e);
}
/**
* HttpURLConnection封装
* @param address
* @param listener
*/
public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try {
URL url = new URL(address);
connection = (HttpURLConnection)url.openConnection();
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
connection.setDoInput(true);
connection.setDoOutput(true);
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder sbd = new StringBuilder();
String line = null;
while (null != (line = reader.readLine())) {
sbd.append(line);
}
// return sbd.toString();
if(null != listener) {
listener.onFinish(sbd.toString());
}
} catch (Exception e) {
e.printStackTrace();
// return e.getMessage();
if(null != listener) {
listener.onError(e);
}
} finally {
if (null != connection) {
connection.disconnect();
}
}
}
}).start();
}
/**
* OkHttpClient封装
* @param address
* @param callback
*/
public static void sendOkHttpRequest(final String address, Callback callback) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(address).build();
client.newCall(request).enqueue(callback);
}
}
HttpUtil
使用:
/**
* HttpURLConnection方式
*/
HttpUtil.sendHttpRequest(url, new HttpUtil.HttpCallbackListener() {
@Override
public void onFinish(String response) {
showResponse(response);
}
@Override
public void onError(Exception e) {
e.printStackTrace();
}
});
/**
* OkHttp方式
*/
HttpUtil.sendOkHttpRequest(url, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
showResponse(response.body().string());
}
});