/*get请求:
主线程跳到子线程再跳回主线程 需要添加到 AndroidManifest.xml中 申请权限
主线程另开一个子线程去处理get请求,防止主线程被卡死
调用自定义get方法 用try catch 设置连接属性 获取回复码 如果一致,获取输入流 将输入流转换成字符串
直接在主线程UI上运行,子线程不能对主线程UI进行操作runOnUiThread(new Runnable() {}
post请求:设置运行输入,输出 Post方式不能缓存,需手动设置为false 请求的数据 打包写入
Android 9.0对http请求的限制:
创建安全配置文件:在res文件夹下创建xml/network-security-config文件
增加cleartextTrafficPermitted属性
添加安全配置文件:AndroidManifest.xml中的Application申明
数据解析:JSONObject是Android官方提供用来解析JSON数据的API。
*/
<uses-permission android:name="android.permission.INTERNET"/>
public class NetworkActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mTextView;
private Button mButton;
private static final String TAG = "NetworkActivity";
private String mResult;
private Button mParseDataButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_network);
findViews();
setListeners();
}
private void findViews() {
mTextView = findViewById(R.id.textView);
mButton = findViewById(R.id.getButton);
mParseDataButton = findViewById(R.id.parseDataButton);
}
private void setListeners() {
mButton.setOnClickListener(this);
mParseDataButton.setOnClickListener(this);
}
//get 主线程跳到子线程再跳回主线程
// 需要添加到AndroidManifest.xml中 <uses-permission android:name="android.permission.INTERNET"/> 申请权限
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.getButton:
//主线程另开一个子线程去处理get请求,防止主线程被卡死
new Thread(new Runnable() {
@Override
public void run() {
//输入URL
String urlString = "http://www.imooc.com/api/teacher?type=2&page=1";
//调用自定义get方法
mResult = requestDataByGet(urlString);
//直接在主线程UI上运行,子线程不能对主线程UI进行操作
runOnUiThread(new Runnable() {
@Override
public void run() {
mResult = decode(mResult);//将Unicode字符转换为UTF-8类型字符串
mTextView.setText(mResult);//把内容输进去
}
});
}
}).start();
break;
//解析数据
case R.id.parseDataButton:
//
if (!TextUtils.isEmpty(mResult)) {
//处理JSON数据
handleJSONData(mResult);
}
break;
}
}
//自定义get方法,请求数据获取,输入参数是 URL 字符串
private String requestDataByGet(String urlString) {
String result = null;
//用try catch
try {
URL url = new URL(urlString);//打开连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//设置连接属性
connection.setConnectTimeout(30000);
connection.setRequestMethod("GET"); // GET POST
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Charset", "UTF-8");
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.connect();//
//获取回复码
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
//如果一致,获取输入流
InputStream inputStream = connection.getInputStream();
result = streamToString(inputStream);//将输入流转换成字符串
} else {
//获取回复信息
String responseMessage = connection.getResponseMessage();
Log.e(TAG, "requestDataByPost: " + responseMessage);
}
} catch (MalformedURLException e) {
//格式错误的 URL 异常
e.printStackTrace();
} catch (IOException e) {
//IO异常
e.printStackTrace();
}
return result;
}
//post请求 "http://www.imooc.com/api/teacher"
// ?type=2&page=1
private String requestDataByPost(String urlString) {
String result = null;
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(30000);
connection.setRequestMethod("POST");
// 设置运行输入,输出:
connection.setDoOutput(true);
connection.setDoInput(true);
// Post方式不能缓存,需手动设置为false
connection.setUseCaches(false);
connection.connect();
// 我们请求的数据: 网址编码器.编码
String data = "username=" + URLEncoder.encode("imooc", "UTF-8")
+ "&number=" + URLEncoder.encode("15088886666", "UTF-8");
// 获取输出流
OutputStream out = connection.getOutputStream();
out.write(data.getBytes());//打包写入
out.flush();//冲洗
out.close();
//
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
Reader reader = new InputStreamReader(inputStream, "UTF-8");
char[] buffer = new char[1024];
reader.read(buffer);
result = new String(buffer);
reader.close();
} else {
String responseMessage = connection.getResponseMessage();
Log.e(TAG, "requestDataByPost: " + responseMessage);
}
final String finalResult = result;
runOnUiThread(new Runnable() {
@Override
public void run() {
mTextView.setText(finalResult);
}
});
//
connection.disconnect();
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//处理解析 JSONObject是Android官方提供用来解析JSON数据的API。
private void handleJSONData(String json) {
try {
JSONObject jsonObject = new JSONObject(json);
//
LessonResult lessonResult = new LessonResult();
ArrayList<LessonResult.Lesson> lessonList = new ArrayList<>();//自定义类的内部类
//
int status = jsonObject.getInt("status");
JSONArray lessons = jsonObject.getJSONArray("data");
//
if (lessons != null && lessons.length() > 0) {
for (int index = 0; index < lessons.length(); index++) {
JSONObject item = (JSONObject) lessons.get(0);
//拿数据
int id = item.getInt("id");
String name = item.getString("name");
String smallPic = item.getString("picSmall");
String bigPic = item.getString("picBig");
String description = item.getString("description");
int learner = item.getInt("learner");
//
LessonResult.Lesson lesson = new LessonResult.Lesson();
lesson.setID(id);
lesson.setName(name);
lesson.setSmallPictureUrl(smallPic);
lesson.setBigPictureUrl(bigPic);
lesson.setDescription(description);
lesson.setLearnerNumber(learner);
//
lessonList.add(lesson);
}
lessonResult.setStatus(status);
lessonResult.setLessons(lessonList);
mTextView.setText("data is : " + lessonResult.toString());
}
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* 将输入流转换成字符串
*
* @param is 从网络获取的输入流
* @return 字符串
*/
public String streamToString(InputStream is) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
baos.close();
is.close();
byte[] byteArray = baos.toByteArray();
return new String(byteArray);
} catch (Exception e) {
Log.e(TAG, e.toString());
return null;
}
}
/**
* 将Unicode字符转换为UTF-8类型字符串
*/
public static String decode(String unicodeStr) {
if (unicodeStr == null) {
return null;
}
StringBuilder retBuf = new StringBuilder();
int maxLoop = unicodeStr.length();
for (int i = 0; i < maxLoop; i++) {
if (unicodeStr.charAt(i) == '\\') {
if ((i < maxLoop - 5)
&& ((unicodeStr.charAt(i + 1) == 'u') || (unicodeStr
.charAt(i + 1) == 'U')))
try {
retBuf.append((char) Integer.parseInt(unicodeStr.substring(i + 2, i + 6), 16));
i += 5;
} catch (NumberFormatException localNumberFormatException) {
retBuf.append(unicodeStr.charAt(i));
}
else {
retBuf.append(unicodeStr.charAt(i));
}
} else {
retBuf.append(unicodeStr.charAt(i));
}
}
return retBuf.toString();
}
}
/*
对象数组以内部类的方式
*/
public class LessonResult {
private int mStatus;
private List<Lesson> mLessons = new ArrayList<>();//Lesson类
public int getStatus() {
return mStatus;
}
public void setStatus(int status) {
mStatus = status;
}
public List<Lesson> getLessons() {
return mLessons;
}
public void setLessons(List<Lesson> lessons) {
mLessons = lessons;
}
//lesson内部类
public static class Lesson {
private int mID;
private String mName;
private String mSmallPictureUrl;
private String mBigPictureUrl;
private String mDescription;
private int mLearnerNumber;
public int getID() {
return mID;
}
public void setID(int ID) {
mID = ID;
}
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public String getSmallPictureUrl() {
return mSmallPictureUrl;
}
public void setSmallPictureUrl(String smallPictureUrl) {
mSmallPictureUrl = smallPictureUrl;
}
public String getBigPictureUrl() {
return mBigPictureUrl;
}
public void setBigPictureUrl(String bigPictureUrl) {
mBigPictureUrl = bigPictureUrl;
}
public String getDescription() {
return mDescription;
}
public void setDescription(String description) {
mDescription = description;
}
public int getLearnerNumber() {
return mLearnerNumber;
}
public void setLearnerNumber(int learnerNumber) {
mLearnerNumber = learnerNumber;
}
@Override
public String toString() {
return "Lesson{" +
"mID=" + mID +
", mName='" + mName + '\'' +
", mSmallPictureUrl='" + mSmallPictureUrl + '\'' +
", mBigPictureUrl='" + mBigPictureUrl + '\'' +
", mDescription='" + mDescription + '\'' +
", mLearnerNumber=" + mLearnerNumber +
'}';
}
}
@Override
public String toString() {
return "LessonResult{" +
"mStatus=" + mStatus +
", mLessons=" + mLessons +
'}';
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<Button
android:id="@+id/getButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="获取数据" />
<Button
android:id="@+id/parseDataButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="解析数据" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:text="结果"
android:textSize="18sp" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted = "true"/>
</network-security-config>