我是刚学习安卓开发,小白一个,很多知识都不懂,查了一些资料才弄明白的,我想应该也有一些同学,刚开始时候也会无从下手。通过这篇文章记录下来,也方便以后查阅。
开发工具:Androit Studio 3.2.1
一 、相关资料
1.Android OKHttp使用详解
2.使用handler ui线程和子线程通讯更新ui示例
3.项目demo下载
二、添加引用和权限
1.创建一个Activity to Mobile 为Empty Avtivity的项目
2.为App添加连网权限(必须添加,否则使用okhttp时候App会崩溃,软件编译阶段正常,使用时候就会崩溃,搞了半天才明白没有添加连网权限)
在AndroidManifest.xml文件中添加
<uses-permission android:name="android.permission.INTERNET" />
3.添加okHttp依赖库
在build.gradle文件中(这个文件名可能有两个,选择文件名有Module:app字样的文件)添加代码
implementation 'com.squareup.okhttp3:okhttp:3.8.1'
implementation 'com.squareup.okio:okio:1.7.0'
上面的代码添加在
dependencies {
代码区
}
基本配置完毕。
三、源代码
1.在MainActivity.java类中
package com.androiduiupdemo;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button button;
private String mBtnTitle = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button);
button.setOnClickListener(this);
}
/* 重要
更新UI操作
*/
public Handler mHandler=new Handler(){
public void handleMessage(Message msg){ //此方法在UI线程中运行(需放到MainActivity.java中)
switch(msg.what){
case 1:
EditText mTxt1 = (EditText)findViewById(R.id.txt1);
mTxt1.setText(msg.getData().getString("m")); // msg.getData().getString("my")获取子线程传过来 '键名' 为my对应的信息,并设置控件UI
mBtnTitle += " 异步 ";
button.setText(mBtnTitle);
break;
case 2:
EditText mTxt2 = (EditText)findViewById(R.id.txt2);
mTxt2.setText(msg.getData().getString("my")); // msg.getData().getString("my")获取子线程传过来 '键名' 为my对应的信息,并设置控件UI
mBtnTitle += " 同步 ";
button.setText(mBtnTitle);
break;
}
}
};
@Override
public void onClick(View v) {
if(v.getId() == R.id.button){
Toast.makeText(this,"test",Toast.LENGTH_LONG).show();
myTest mytest = new myTest(this); //实例化myTest类
mytest.getDataAsyn("http://baidu.com",1); //调用异步请求
mytest.getDataSyn("http://qq.com",2); //调用同步请求
}
}
}
2.新创建一个类文件,名字为myTest
在myTest.java中用到okHttp类库的异步和同步请求方法,具体区别请查阅文章头部的相关资料
package com.androiduiupdemo;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class myTest {
private MainActivity mActivity;
public myTest(MainActivity mainActivity){ //将主线程类传进来,后面向UI线程发送消息时候需要
this.mActivity = mainActivity;
}
/*异步获取网页源码 需要用到okHttp类库
*参数String url 访问的网站
* 参数int i 识别码 switch case中需要用到
*/
public void getDataAsyn(final String url , final int i) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url) //设置访问网址
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){//回调的方法执行在子线程。
String mResult = response.body().string(); //获取网页返回内容
Log.d("myTs","异步获取数据成功了");
Log.d("myTs","response.code()=="+response.code());
Log.d("myTs","response.body().string()==" + mResult );
//向UI线程发送消息
Message msg = new Message();
Bundle mdata = new Bundle();
mdata.putString("my",mResult); //这里的数据是 ‘键 => 值’ 类型的对应,在MainActivity.java的handleMessage方法中使用
msg.setData(mdata);
msg.what = i; //i的值由参数传进来,用于在MainActivity.java的handleMessage方法中识别执行哪一个case 语句, 当然i的类型可以定义成其它的。
mActivity.mHandler.sendMessage(msg); //向主UI线程发送消息,不在MainActivity的线程需要 调用主类名才可以发送消息给主UI线程
}
}
});
}
/*同步获取网页源码 需要用到okHttp类库
*参数String url 访问的网站
* 参数int i 识别码 在switch case中需要用到
*/
public void getDataSyn(final String url,final int i){
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象
Request request = new Request.Builder()
.url(url)//请求接口。如果需要传参拼接到接口后面。
.build();//创建Request 对象
Response response = client.newCall(request).execute();//得到Response 对象
if (response.isSuccessful()) {
String mResult = response.body().string();
Log.d("kwwl","response.code()=="+response.code());
Log.d("kwwl","response.message()=="+response.message());
Log.d("kwwl","res==" + mResult);
//向UI线程发送消息
Message msg = new Message();
Bundle mdata = new Bundle();
mdata.putString("my",mResult); //这里的数据是 ‘键 => 值’ 类型的对应,在MainActivity.java的handleMessage方法中使用
msg.setData(mdata);
msg.what = i; //i的值由参数传进来,用于在MainActivity.java的handleMessage方法中识别执行哪一个case 语句, 当然i的类型可以定义成其它的。
mActivity.mHandler.sendMessage(msg); //向主UI线程发送消息,不在MainActivity中类里面创建的线程,需要调用主类名才可以发送消息给主UI线程
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
3.主界面图,点击‘获取数据’会通过网络线程获取源码,并且更新两个EditText文本框信息