实验七 网络通信
1、实验目的
(1) 掌握Andriod中web网络通信程序
2、实验要求
(1) 认真填写实验报告,要求附加部分运行界面和主要代码;
(2) 对设计好的程序,检查输出是否符合预期,如有错请分析错误原因并解决;
3、实验内容
(1) 掌握JSON文件的解析,掌握GSon的使用;
(2) 掌握Volley中RequestQueue、JSonRequest、JSonArrayRequest的使用;
(3) 实现一个多Activity的Web服务客户端,主界面可访问学生列表并显示,选择某个学生后在第二个界面详细显示该学生的所有信息;
效果图
再上代码 接着上步骤
MainActivity.java
package com.example.network;
import android.content.Intent;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageRequest;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.json.JSONArray;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
static final String UrlBase = "http://10.0.1.2/";
static final String Urlhome = UrlBase+"piclist.php";
RecyclerView recyclerView;
MyRecyclerAdapter adapter;
// 网络请求一个数组,这里面包含学生。(因为json外面的括号是[])
ArrayList<Student> students;
// 实现从网上拿到json串,转换成学生数组对象
// 请求队列
RequestQueue queue;
// 新建一个数组请求
JsonArrayRequest jsonArrayRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recylerview);
// 保留cookie会话 请我的手机模拟浏览器也保留会话
CookieHandler.setDefault(new CookieManager());
/*
// 新建一个列表布局 朝向垂直
LinearLayoutManager manager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
// recyclerView您的布局是一个列表形式的
recyclerView.setLayoutManager(manager);
*/
// 用阁式布局来做 新建一个布局
GridLayoutManager manager1 = new GridLayoutManager(this,2);
// recyclerView您的布局是一个阁式布局形式的
recyclerView.setLayoutManager(manager1);
// recyclerView的适配器
adapter = new MyRecyclerAdapter();
recyclerView.setAdapter(adapter);
// 定义一个队列
queue = Volley.newRequestQueue(this);
// 数组请求
jsonArrayRequest = new JsonArrayRequest(Urlhome, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
// json数组转换成学生数组 一句话搞定
Gson gson = new Gson();
students = gson.fromJson(response.toString(),new TypeToken<ArrayList<Student>>(){}.getType());
// 通知刷新界面
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
// 把请求加到队列里面
queue.add(jsonArrayRequest);
}
public void Refresh(View view){
queue.add(jsonArrayRequest);
}
// 新建一个适配器
class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder>{
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
// 先去准备一个显示学生的布局文件
// 从资源文件恢复一个布局文件成视图
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_student,viewGroup,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull final ViewHolder viewHolder, int i) {
// 拿到一个学生
final Student student = students.get(i);
// 拿到学生后送到布局里面
viewHolder.textView.setText(student.getStuName());
// imageView是一个地址 要从网上下载 所以新建一个图片请求
ImageRequest imageRequest = new ImageRequest(UrlBase + student.getImagePath(), new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
// 请求成功相应一个图片 直接把图片带进viewholder
viewHolder.imageView.setImageBitmap(response);
}
}, 0, 0, ImageView.ScaleType.CENTER, Bitmap.Config.ARGB_8888, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
// 把请求加到队列里面
queue.add(imageRequest);
// 点击某一个时 显示详细信息,由于用到recyclerView 只能在onBindViewHolder里面加
// 加上相应事件
// 我的viewHolder它的itemView(最上面的父视图,点图片也好,名字也好。。。都要切换到下一个界面)
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 定义一个意图来跳转到下一个界面
Intent intent = new Intent(MainActivity.this,StudentActivity.class);
// 学生定义成final 且实现序列化
intent.putExtra("student",student);
startActivity(intent);
}
});
}
@Override
public int getItemCount() {
if(students == null) return 0;
// 返回学生的大小
return students.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
// 令你新建布局文件里面的东东
ImageView imageView;
TextView textView;
public ViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageView);
textView = itemView.findViewById(R.id.textView);
}
}
}
}
Student.java
package com.example.network;
import java.io.Serializable;
public class Student implements Serializable {
// 这些名字需要与json 的命名相同
private String stuName;
private String stuNo;
private String stuGender;
private String imagePath;
private String stuClass;
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public String getStuNo() {
return stuNo;
}
public void setStuNo(String stuNo) {
this.stuNo = stuNo;
}
public String getStuGender() {
return stuGender;
}
public void setStuGender(String stuGender) {
this.stuGender = stuGender;
}
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
public String getStuClass() {
return stuClass;
}
public void setStuClass(String stuClass) {
this.stuClass = stuClass;
}
}
StudentActivity.java
package com.example.network;
import android.content.Intent;
import android.graphics.Bitmap;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageRequest;
import com.android.volley.toolbox.Volley;
public class StudentActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_student);
// 得到意图
Intent intent = getIntent();
// 恢复学生
Student student = (Student) intent.getSerializableExtra("student");
TextView text_name = findViewById(R.id.text_name);
TextView text_gender = findViewById(R.id.text_gender);
TextView text_class = findViewById(R.id.text_class);
text_name.setText("姓名: "+student.getStuName());
text_gender.setText("性别: "+student.getStuGender());
text_class.setText("班级: "+student.getStuClass());
// 里面访问了所以要生成final
final ImageView imageView = findViewById(R.id.imageView2);
// 又从网上下载图片
// 新建一个队列 或者 在MainActivity.java把队列定义成整个app共享 如下;
// queue = Volley.newRequestQueue(getApplicationContext()); 这个java文件还是要加上这句 所以我再新建一个
RequestQueue queue = Volley.newRequestQueue(this);
ImageRequest imageRequest = new ImageRequest(MainActivity.UrlBase + student.getImagePath(), new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
imageView.setImageBitmap(response);
}
}, 0, 0, ImageView.ScaleType.CENTER, Bitmap.Config.ARGB_8888, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
// 把请求加到队列里面
queue.add(imageRequest);
}
}