<TextView
android:id=“@+id/joke_tv_title”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_gravity=“center”
android:text=“title”
android:textColor=“@android:color/black”
android:textSize=“18sp” />
<TextView
android:id=“@+id/joke_tv_content”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_margin=“5dp”
android:text=“content”
android:textColor=“@android:color/black”
android:textSize=“16sp” />
<ImageView
android:id=“@+id/joke_iv_content”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_margin=“5dp”
android:adjustViewBounds=“true”
android:scaleType=“fitXY” />
<TextView
android:id=“@+id/joke_tv_time”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_margin=“5dp”
android:gravity=“right”
android:text=“时间”
android:textSize=“14sp” />
上面的布局是每一个笑话内容显示的布局设计
4.创建一个json解析和数据收集的类
package com.lwz.conn;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.Serializable;
import java.util.ArrayList;
/**
-
这是一个数据解析的工具类,
-
-
这里是从源码中取出属性值
-
这里是使用从外到内一层一层的去获取资源数据,最里面一层的数据才是我们要显示在页面上的数据
-
这里的处理的方式是比较麻烦的一种,其中它处理的方式可以有好几种
-
这里的数据层层嵌套,就像xml资源的子标签一样
*/
/*下面是提供API网站给我们的数据的提示,xml文件中下面的某些变量,我们可以选择性的去使用,
但是这些变量的名字是固定的,更改了就获取不到了
allNum String 345 所有记录数
allPages String 45 所有页数。每页20条。
contentlist JokeItem[] 笑话条目内容
-
title String 吃了一百年的玉米 笑话标题
-
text String 笑话正文
-
ct String 2015-07-10 05:54:00.000 生成时间
currentPage String 1 当前第几页
maxResult String 20 每页最多显示几条*/
//因为要Intent来实现数据的传递,所以要实现序列化
public class JokeBean implements Serializable {
//最外层的属性值
int showapi_res_code;
String showapi_res_error;
Body showapi_res_body;//这个才是有用的信息数据,上面的实现其实也是可以不用去定义的
@Override
public String toString() {
return “JokeBean{” +
“showapi_res_body=” + showapi_res_body +
“, showapi_res_code=” + showapi_res_code +
“, showapi_res_error='” + showapi_res_error + ‘’’ +
‘}’;
}
class Body implements Serializable {
int allNum;
int allPages;
int currentPage;//当前第几页
int maxResult;
int ret_code;
ArrayList contentlist;
@Override
public String toString() {
return “Body{” +
“allNum=” + allNum +
“, allPages=” + allPages +
“, currentPage=” + currentPage +
“, maxResult=” + maxResult +
“, ret_code=” + ret_code +
“, contentlist=” + contentlist +
‘}’;
}
class Content implements Serializable {
String id;
String ct;//生成时间
String text;//笑话正文
String title;//笑话标题
int type;//文本笑话,图片笑话,动态图笑话
String img;//笑话的图片连接地址URL
//重写toString方法,查看数据
@Override
public String toString() {
return “Content{” +
“ct='” + ct + ‘’’ +
“, id='” + id + ‘’’ +
“, text='” + text + ‘’’ +
“, title='” + title + ‘’’ +
“, type=” + type +
“, img='” + img + ‘’’ +
‘}’;
}
}
}
/**
-
创建一个静态的转换方法
-
将字符串使用json解析的方式,转换成对象
-
用于把资源代码的字符串中某些值赋值给某些需要的变量
*/
public static JokeBean getBeanValue(String json) {
try {
//1.将最外层的字符串,转换为json对象
JSONObject jsonObject = new JSONObject(json);
//2.创建返回的对象
JokeBean jokeBean = new JokeBean();
//3.取外层的数据,两种方法opt和get,其中opt更好,get在数据不匹配时会报错
jokeBean.showapi_res_code = jsonObject.optInt(“showapi_res_code”);
jokeBean.showapi_res_error = jsonObject.optString(“showapi_res_error”);
//4.取第二层数据,是一个对象
JSONObject bodyObject = jsonObject.optJSONObject(“showapi_res_body”);
//5.通过这个对象的值,再去取数据
//创建内部对象,把获取到的数据赋值给这个类的对象
Body body = jokeBean.new Body();
body.allNum = bodyObject.optInt(“allNum”);
body.allPages = bodyObject.optInt(“allPages”);
body.currentPage = bodyObject.optInt(“currentPage”);
body.maxResult = bodyObject.optInt(“maxResult”);
body.ret_code = bodyObject.optInt(“ret_code”);
//Log.e(“TAG”, “jokeBean------------>” + jokeBean.toString());
// Log.e(“TAG”, “body------------>” + body.toString());
//这里的contentlist的数据是数组类型的!
JSONArray array = bodyObject.optJSONArray(“contentlist”);
//创建一个集合用来存放数组
body.contentlist = new ArrayList<>();
//通过数据遍历循环去取所有的对象
for (int i = 0; i < array.length(); i++) {
Body.Content content = body.new Content();
//再次使用json解析数据
//集合通过optXXX(index)的方法去取值
JSONObject obj = array.optJSONObject(i);
content.ct = obj.optString(“ct”);//笑话的创建时间
content.id = obj.optString(“id”);//笑话的id编号
content.title = obj.optString(“title”);//笑话的标题
content.type = obj.optInt(“type”);//笑话的类别,1代表文本,2代表图像
//对类别的判断
if (content.type == 2) {
content.img = obj.optString(“img”);
} else {
content.text = obj.optString(“text”);
}
body.contentlist.add(content);
}
//Log.e(“TAG”, “body.c------------>” + body.contentlist.toString());
jokeBean.showapi_res_body = body;
//返回一个JokeBean对象,里面包含所有的数据
return jokeBean;
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
5.创建一个异步任务类,用来下载json数据
package com.lwz.conn.utils;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;
import com.lwz.conn.JokeBean;
import com.lwz.conn.ShowActivity;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
-
异步任务的创建
-
这里的任务是下载网络的资源文件
*/
public class MyAsyncTask extends AsyncTask<String, Void, String> {
Context context;
public MyAsyncTask(Context context) {
this.context = context;
}
//在子线程中做资源的下载
@Override
protected String doInBackground(String… params) {
try {
//从params中获取传过来的URL
URL url = new URL(params[0]);
Log.e(“TAG”, params[0]);
//使用URLconnection的子类HttpURLconnection来请求连接更好
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);//设置要读取文件
conn.setConnectTimeout(10000);//设置连接的最长时间
InputStream is = conn.getInputStream();//获取连接的输入流
ByteArrayOutputStream baos = new ByteArrayOutputStream(); //创建一个高速的输出流来读取输入流
//对数据的读取(边读边取)
int len = 0;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1) {
baos.write(buf, 0, len);
}
//获得的输出流变成String类型的字符串,用于最后的返回
String result = new String(baos.toByteArray(), “utf-8”);//设置编码格式
//返回的是获取的一大串文本资源源码
Log.e(“TAG”,“-------------->”+ result);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//任务完成后页面的跳转,把相关数据带到要跳转的页面
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//这里接收的s,就是从网络中获取到的一大串字符串的文件源码
//这里要使用json解析,从源码中来获取我们需要的数据
Log.e(“TAG”, s);
JokeBean jokeBean = JokeBean.getBeanValue(s);
//页面的跳转
Intent intent = new Intent(context, ShowActivity.class);
intent.putExtra(“jokeBean”, jokeBean); //数据传递
context.startActivity(intent);//开始跳转
}
}
6.MainActivity.java
package com.lwz.conn;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.lwz.conn.utils.MyAsyncTask;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
/***
- Android网络请求示例
*/
public class MainActivity extends AppCompatActivity {
//定义布局内的控件
TextView textView;
CheckBox checkBox;
EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//实例化控件
textView = (TextView) findViewById(R.id.main_tv);
checkBox = (CheckBox) findViewById(R.id.main_cb_isImage);
editText = (EditText) findViewById(R.id.main_et_pager);
}
//第一个按钮的回调方法
//这里请求的数页面数据的源码资源
public void conn1(View v) {
//所有的网络资源请求都是子线程中进行的
new Thread(new Runnable() {
@Override
public void run() {
//资源下载的实际代码
try {
//设置URL
URL url = new URL(“http://route.showapi.com/341-1?showapi_appid=27155&time=&page=&maxResult=&showapi_sign=5bd3b5774c2346068463b526171ba86e”);
// URL url = new URL(“https://www.baidu.com”);
//打开连接使用openConnection方法
URLConnection conn = url.openConnection();
//必须要对连接对象做相关的设置
conn.setConnectTimeout(10000);//设置连接的最长时间
conn.setDoOutput(true);//用于设置是否从连接中读取数据,如果参数值为true时,表示读取数据,否则不读取数据
//这里写数据使用setDoInput(boolean newValue),我也是感觉比较奇怪的地方!
//获取输入流
InputStream is = conn.getInputStream();
//对流里面的数据进行读取
int len = 0;
byte[] buf = new byte[1024];
final StringBuilder sb = new StringBuilder();
while ((len = is.read(buf)) != -1) {
sb.append(new String(buf, 0, len));
}
is.close();//关闭流
//把获取的字符串数据显示在UI文本中,但是要在主线程中进行
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(sb.toString());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
//连接并处理网络文件,用自定义的布局显示出来
public void conn2(View view) {
//get请求使用?来拼接参数,多个参数使用&符号
//判断是显示图片还是显示文本信息
boolean isImage = checkBox.isChecked();
//确定URL的链接地址
// 这里的showapi_appid和showapi_sign都要自己上网注册使用自己的账号的应用信息。
String baseURL = “”;
if (isImage) {
baseURL = “http://route.showapi.com/341-2?showapi_appid=27155&showapi_sign=5bd3b5774c2346068463b526171ba86e&page=”;
} else {
baseURL = “http://route.showapi.com/341-1?showapi_appid=27155&showapi_sign=5bd3b5774c2346068463b526171ba86e&page=”;
}
int pageNum = 1;//定义more的页码数
String pageString = editText.getText().toString(); //获取用户输入页数
try {
pageNum = Integer.parseInt(TextUtils.isEmpty(pageString) ? “1” : pageString);
if (pageNum <= 1) {
pageNum = 1;
}
} catch (Exception e) {
Toast.makeText(this, “你输入的页码数有误!”, Toast.LENGTH_SHORT).show();
}
baseURL += pageNum;
//使用异步任务来加载数据,在异步任务里面,任务完成后做页面跳转
MyAsyncTask task = new MyAsyncTask(MainActivity.this);
task.execute(baseURL);
}
}
7.设计另一个显示笑话的显示类
package com.lwz.conn;
最后
由于文章篇幅原因,我只把面试题列了出来,详细的答案,我整理成了一份PDF文档,这份文档还包括了还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 ,帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!