添加权限
Manitest.xml 文件中添加访问权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
application 节点下添加
android:usesCleartextTraffic="true"
build.gradle 文件中添加依赖
implementation 'org.xutils:xutils:3.8.5'
activity.java
//替代onCreate方法中的 setContentView(R.layout.activity_main);
@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
@ViewInject(R.id.textView)
TextView textView1;
@ViewInject(R.id.textView2)
TextView textView2;
@ViewInject(R.id.imageView)
ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
x.Ext.init(getApplication());
x.Ext.setDebug(BuildConfig.DEBUG);// 是否输出debug日志, 开启debug会影响性能.
x.view().inject(this);//没有用到view注解可以先不用
// textView1 = findViewById(R.id.textView);
// textView2 = findViewById(R.id.textView2);
ImageOptions imageOptions;
imageOptions = new ImageOptions.Builder()
.setSize(DensityUtil.dip2px(120), DensityUtil.dip2px(120))
.setRadius(DensityUtil.dip2px(5))
// 如果ImageView的大小不是定义为wrap_content, 不要crop.
.setCrop(true) // 很多时候设置了合适的scaleType也不需要它.
// 加载中或错误图片的ScaleType
//.setPlaceholderScaleType(ImageView.ScaleType.MATRIX)
.setImageScaleType(ImageView.ScaleType.CENTER_CROP)
.setLoadingDrawableId(R.mipmap.ic_launcher)
.setFailureDrawableId(R.mipmap.ic_launcher)
.build();
x.image().bind(mImageView, "https://5b0988e595225.cdn.sohucs.com/images/20170922/fe15d13a3e764a3bbaede340e47692ca.jpeg", imageOptions);//加载图片的控件,和加载网络图片的地址
RequestParams params = new RequestParams("http://148.70.46.9/object3");
x.http().get(params, new Callback.CommonCallback<String>() {
@Override
public void onSuccess(String result) {//主线程
Log.i("Main","result"+result);
textView1.setText(result);//进行UI操作
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
Log.i("Main","onError"+ex.getMessage());
textView1.setText("网络出错"); }
@Override
public void onCancelled(CancelledException cex) {
}
@Override
public void onFinished() {
}
});
}
@Event(value = {R.id.button,R.id.button2},//用大括号把按钮按照 R.id.格式放进去
type = View.OnClickListener.class/*可选参数, 默认是View.OnClickListener.class*/)
private void onTest1Click(View view) {
switch (view.getId()){
case R.id.button:
Log.i("button","onclick-----button1");
break;
case R.id.button2:
Log.i("button","onclick-----button2");
break;
}
}
}
xml文件代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="110dp"
android:layout_marginTop="88dp"
android:layout_marginBottom="413dp"
app:layout_constraintBottom_toTopOf="@+id/imageView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="27dp"
app:layout_constraintStart_toStartOf="@+id/textView"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="111dp"
android:layout_marginLeft="111dp"
android:layout_marginTop="98dp"
android:text="Button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="27dp"
android:layout_marginLeft="27dp"
android:layout_marginTop="78dp"
android:text="Button"
app:layout_constraintStart_toStartOf="@+id/button"
app:layout_constraintTop_toBottomOf="@+id/button" />
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="101dp"
android:layout_marginLeft="101dp"
android:layout_marginBottom="111dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
开 讲
前面讲到了JSON解析,不过我们前面 所学习的json是存在一些问题的,
问题一:每次取数据对应的key,完全不能出错,出错了解析就会中断
问题二:对于复杂的JSON字符串,解析起来特别麻烦
问题三:有时候数据多了,还要创建一个实体类 来存数据
对于这些问题接下来,我向小伙伴们介绍一个框架-GSON框架
Gson是谷歌官方推出的支持JSON和Java 0ject相关转换的开源Java库。
开源地址: https://github.com/google/gson
优点:
第一步,导入依赖包
implementation 'com.google.code.gson:gson:2.8.6'
案例1:
IP地址: http://148.70.46.9/object
json数据:{ “age”:30,“name”:“张三”, “isstudent”:true }
分析数据结构
第一步,修改端口,并且创建实体类(实体类变量名和json数据中key对应)
public class Student {
public int age;
public String name;
public boolean isstudent;
}
第二步,创建Gson对象,然后获取实体类对应的数据
我们可以通过断点来查看一下
对比之前json解析的方法
可以看出Gson解析省去了这些通过对应字段去取数据的步骤,而是可以直接帮我们解析实体类对应字段的值
这里补充一下,如果在实体类中,如果把属性设为私有类型的话,记得要Getter 和Setter
演示步骤
最后格式
案例二:
IP地址:http://148.70.46.9/object1
json数据:{ “age”:20,“name”:“张三”, “isstudent”:true,“class”:{“grade”:“18级”,“classname”:“中医学”} }
分析数据结构
//json数据:{ "age":20,"name":"张三", "isstudent":true,"class":{"grade":"18级","classname":"中医学"} }
public class Student {
public int age;
public String name;
public boolean isstudent;
@SerializedName("class")//对 class1 的注解
public MyClass class1;//class是java关键词,我们不能给变量起名为class
public class MyClass{//创建类
public String grade;
public String classname;
}
}
然后,activity里的代码只需要修改接口,其他的都不用改
案例三:
IP地址:http://148.70.46.9/array
json数据:[ “张三”, “李四”, “王五” ]
分析数据结构
我们可以看到这是一个字符串数组,不是一个json对象,那我们就用一个字符串数组来接收,解析方法不变
代码
Gson gson=new Gson();//创建Gson对象
String[] strings=gson.fromJson(result,String[].class);
案例四:
IP地址: http://148.70.46.9/object4
json数据:[ { “id”:“001”,“age”:30,“name”:“张三”, “isstudent”:false }, { “id”:“002”,“age”:25,“name”:“李四”,
“isstudent”:true }, { “id”:“003”,“age”:26,“name”:“王五”, “isstudent”:true } ]
分析数据结构
第一步,分析可以知道,案例四的json数据是一个数组对象,里面是json对象,所以我们想给json对象创建实体类
//json数据:{ "id":"001","age":30,"name":"张三", "isstudent":false },
public class Student {
public String id;
public int age;
public String name;
public boolean isstudent;
}
Gson gson=new Gson();//创建Gson对象
List<Student> list=gson.fromJson(result,new TypeToken<ArrayList<Student>>(){}.getType());
案例五:
IP地址:http://148.70.46.9/object3
json数据:{ “grade”:“18级”,“classname”:“中医学”,“students”:[ { “id”:“001”,“age”:30,“name”:“张三”,
“isstudent”:false }, { “id”:“002”,“age”:25,“name”:“李四”, “isstudent”:true }, {
“id”:“003”,“age”:26,“name”:“王五”, “isstudent”:true } ]}
分析数据结构
我们也可以把json数据格式化一下
因为最外面一层是json对象,所以第一步先创建实体类对象
代码
public class Student {
public String grade;
public String classname;
public ArrayList<MyStudent> students=new ArrayList<>();
public class MyStudent{
public String id;
public int age;
public String name;
public boolean isstudent;
}
}
Gson gson=new Gson();//创建Gson对象
Student student=gson.fromJson(result,Student.class);//第一个值传json数据,第二个值传解析的类型
总结:json数据如果是大括号{}开头的,我们就把它解析成一个对象,如果是中括号【】开头的,我们就把它解析到一个List<>里面
我们可以发现,使用Gson解析json数据最麻烦的地方也就是创建实体类了,相对于之前的解析方法,Gson解析起来方便多了
但是,在Android 的世界里,总是会有便捷的方法来帮助我们解决问题,对于创建实体类我们也有好方法
第一步,先把原来实体类的创建的变量删掉,空白处右键,然后点击Generate
选择GsonFormat
贴入我们要解析的数据
全选,ok,帅不帅
运行
没有这个插件的小伙伴,可以到设置里面的Plugins里面下载
textView1.setText(student.getClassname());//进行UI操作
小伙伴们,关于JSON解析第三方框架Gson就讲到这里啦,是不是感觉现在写程序越来越方便了,还有很多更加高级的功能在后面等着你哦,谢谢您的阅读,我们继续冲冲冲
Android 入门第七讲01-数据存储(数据存储概述,文件存储(raw和asserts目录读写,data/data/包名目录读写,sdcard目录读写),SharedPreferences读写)