• 第一阶段:冲刺6(热搜界面完成)Android通过异步加载获取数据


    昨天把花了很多时间把热搜界面设计出来了,今天也终于把热搜界面完成了。思想是用了异步加载数据,和java的ajax类似。获取数据就是通过一个网络请求来获得数据库的内容。具体实现效果看下图

    上面三个图是用的异步加载获取的数据(进入首页即可获得数据,不用点击),三个按键是之前的测试数据。参考微博热搜和QQ热搜界面,设计成这样的,不好看。数据是从数据库里读取的4.17日阅读量最多的前50篇文章。具体了解界面看上一篇博客。

    因为要通过网络获取数据,所以得需要添加访问网络的依赖

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    

    在res新建一个xml文件夹,新建一个network_security_config.xml

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <base-config cleartextTrafficPermitted="true" />
    </network-security-config>
    

    在AndroidManifest.xml的appliacationn里添加以下语句

    android:usesCleartextTraffic="true"
    android:networkSecurityConfig="@xml/network_security_config">
    

    这样网络请求就不会报错了。(我的网络请求出了好多错,把这两个加上就没问题了)

    具体思路:通过异步请假,发送网络请求,请求数据库数据,返回json格式。因为查询的是多条,所以最后会返回的是json的数组,需要通过gson.fromJson()方法,转换成我们list数组。

    代码在昨天的基础上加了很多东西,当然也有一些测试的(删除全部信息,插入等)。

    New_实体类
      
    package com.example.hotsearch;
    

    import androidx.room.ColumnInfo;
    import androidx.room.Entity;
    import androidx.room.PrimaryKey;

    @Entity
    public class New_ {
    @PrimaryKey(autoGenerate = true)
    private int id;
    // @ColumnInfo(name = "评论数量")
    private int commentCount;
    // @ColumnInfo(name = "阅读量")
    private int priority;
    // @ColumnInfo(name = "来源")
    private String source;
    // @ColumnInfo(name = "标题")
    private String title;
    // @ColumnInfo(name = "摘要")
    private String digest;
    // @ColumnInfo(name = "图片地址")
    private String imgsrc;
    // @ColumnInfo(name = "时间")
    private String ptime;
    // @ColumnInfo(name = "正文")
    private String zw;
    // @ColumnInfo(name = "类型")
    private String type;
    private Boolean history = false;

    public New_(int priority, String title) {
        this.priority = priority;
        this.title = title;
    }
    
    public Boolean getHistory() {
        return history;
    }
    
    public void setHistory(Boolean history) {
        this.history = history;
    }
    
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public int getCommentCount() {
        return commentCount;
    }
    
    public void setCommentCount(int commentCount) {
        this.commentCount = commentCount;
    }
    
    public int getPriority() {
        return priority;
    }
    
    public void setPriority(int priority) {
        this.priority = priority;
    }
    
    public String getSource() {
        return source;
    }
    
    public void setSource(String source) {
        this.source = source;
    }
    
    public String getTitle() {
        return title;
    }
    
    public void setTitle(String title) {
        this.title = title;
    }
    
    public String getDigest() {
        return digest;
    }
    
    public void setDigest(String digest) {
        this.digest = digest;
    }
    
    public String getImgsrc() {
        return imgsrc;
    }
    
    public void setImgsrc(String imgsrc) {
        this.imgsrc = imgsrc;
    }
    
    public String getPtime() {
        return ptime;
    }
    
    public void setPtime(String ptime) {
        this.ptime = ptime;
    }
    
    public String getZw() {
        return zw;
    }
    
    public void setZw(String zw) {
        this.zw = zw;
    }
    
    public String getType() {
        return type;
    }
    
    public void setType(String type) {
        this.type = type;
    }
    

    }

    Adapter适配器
      
    package com.example.hotsearch;
    

    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.EditText;
    import android.widget.TextView;
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;

    import java.util.ArrayList;
    import java.util.List;

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    List<New_> allNews = new ArrayList<>();

    public void setAllNews(List<New_> allNews) {
        this.allNews = allNews;
    }
    
    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        View itemViem = layoutInflater.inflate(R.layout.cell_normal, parent,false);
        return new MyViewHolder(itemViem);
    }
    
    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        New_ new_ = allNews.get(position);
        holder.textViewNumber.setText(String.valueOf(position+1));
        holder.editTextTitle.setText(new_.getTitle());
        holder.editTextTitle.setEnabled(false);
        holder.editTextTitle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
    
            }
        });
        holder.textViewSearchNum.setText(new_.getPriority()+"人查询");
    }
    
    @Override
    public int getItemCount() {
        return allNews.size();
    }
    
    //用来管理我们新建的ConstraintLayout
    static class MyViewHolder extends RecyclerView.ViewHolder {
        TextView textViewNumber,textViewSearchNum;
        EditText editTextTitle;
        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            textViewNumber = itemView.findViewById(R.id.textViewNumber);
            editTextTitle = itemView.findViewById(R.id.editTextTitle);
            textViewSearchNum = itemView.findViewById(R.id.textViewSearchNum);
        }
    }
    

    }

    NewsDao
      
    package com.example.hotsearch;
    

    import androidx.lifecycle.LiveData;
    import androidx.room.Dao;
    import androidx.room.Insert;
    import androidx.room.Query;

    import java.util.List;

    @Dao
    public interface NewsDao {
    @Insert
    public void insertNews(New_...new_s);
    @Query("SElECT * FROM New_")
    public LiveData<List<New_>> getAllNewsLive();
    @Query("DELETE FROM New_")
    public void deleteAllNews();
    }

    ************读取的可不是这个数据库,这个数据库是存放我们的新闻,和我们读取的没关系。真正读取的是我们自己的mysql数据库
    NewsDatabase(数据库)
      
    package com.example.hotsearch;
    

    import android.content.Context;

    import androidx.room.Database;
    import androidx.room.Room;
    import androidx.room.RoomDatabase;
    @Database(entities = {New_.class},version = 1,exportSchema = false)
    public abstract class NewsDatabase extends RoomDatabase {
    private static NewsDatabase INSTANCE;
    static synchronized NewsDatabase getDatabase(Context context){
    if(INSTANCE == null){
    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),NewsDatabase.class,"new_database")
    .allowMainThreadQueries()
    .build();
    }
    return INSTANCE;
    }
    public abstract NewsDao getNewsDao();

    工程类添加了网络请假方法和内部类来实现我们的异步请求

    NewsRepository
      
    package com.example.hotsearch;
    

    import android.content.Context;
    import android.os.AsyncTask;
    import android.util.Log;

    import androidx.lifecycle.LiveData;

    import com.google.gson.Gson;
    import com.google.gson.reflect.TypeToken;

    import java.io.ByteArrayOutputStream;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.List;

    public class NewsRepository {
    private LiveData<List<New_>> allNews;
    private NewsDao newsDao;
    public NewsRepository(Context context) {
    NewsDatabase wordDatabase = NewsDatabase.getDatabase(context.getApplicationContext());
    newsDao = wordDatabase.getNewsDao();
    allNews = newsDao.getAllNewsLive();
    }

    public LiveData<List<New_>> getAllNews() {
        return allNews;
    }
    // 定义类的接口-- 插入
    public void insertNews(New_...news){
        new InsertAsyncTask(newsDao).execute(news);
    }
    public void deleteNews(){
        new DeleteAsyncTask(newsDao).execute();
    }
    // 插入类
    static class InsertAsyncTask extends AsyncTask<New_,Void,Void> {
        private NewsDao newsDao;
        public InsertAsyncTask(NewsDao newsDao) {
            this.newsDao = newsDao;
        }
        // 将在主线程的工作放到后台来执行
        @Override
        protected Void doInBackground(New_...new_s) {
           newsDao.insertNews(new_s);
            return null;
        }
    }
    // 删除类
    static class DeleteAsyncTask extends AsyncTask<New_,Void,Void> {
        private NewsDao newsDao;
        public DeleteAsyncTask(NewsDao newsDao) {
            this.newsDao = newsDao;
        }
        // 将在主线程的工作放到后台来执行
        @Override
        protected Void doInBackground(New_...new_s) {
            newsDao.deleteAllNews();
            return null;
        }
    }
    // 创建一个内部类来实现 ,在实现下面内部类之前,需要自定义的Bean对象来封装处理Josn格式的数据
    class  NewsAsyncTask extends AsyncTask<String,Void,List<New_>>{
        @Override
        protected List<New_> doInBackground(String... strings) {
             getJson(strings[0]);
            return null;
        }
    }
    public void getJson(final String address) {
        new Thread(new Runnable(){
            @Override
            public void run() {
                HttpURLConnection connection = null;
                try {
                    URL url = new URL(address);
                    Log.d("address",address);
                    connection=(HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("POST");
                    connection.setConnectTimeout(10000);
                    connection.setReadTimeout(5000);
                    connection.connect();
                    int code=connection.getResponseCode();
                    if(code==200){
                        InputStream is=connection.getInputStream();
                        String state = getStringFromInputStream(is);
                        Gson gson = new Gson();
                        List<New_> list = gson.fromJson(state,new TypeToken<List<New_>>(){}.getType());
                        for (int i=0;i<50;i++){
                            New_ new_2 = new New_(list.get(i).getPriority(),list.get(i).getTitle());
                            newsDao.insertNews(new_2);
                        }
                    }
    
                } catch (Exception e) {
                    e.printStackTrace();
                }finally{
                    if(connection!=null){
                        connection.disconnect();
                    }
                }
            }
        }).start();
    
    }
    private static String getStringFromInputStream(InputStream is) throws Exception{
    
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        byte[] buff=new byte[1024];
        int len=-1;
        while((len=is.read(buff))!=-1){
            baos.write(buff, 0, len);
        }
        is.close();
        String html=baos.toString();
        baos.close();
        return html;
    }
    

    }

    NewsViewModel
      
    package com.example.hotsearch;
    

    import android.app.Application;

    import androidx.annotation.NonNull;
    import androidx.lifecycle.AndroidViewModel;
    import androidx.lifecycle.LiveData;

    import java.util.List;

    public class NewsViewModel extends AndroidViewModel {
    private NewsRepository newsRepository;
    public NewsViewModel(@NonNull Application application) {
    super(application);
    newsRepository = new NewsRepository(application);
    }

    public LiveData<List<New_>> getAllNews() {
        return newsRepository.getAllNews();
    }
    
    // 定义类的接口-- 插入
    public void insertWords(New_...news){
       newsRepository.insertNews(news);
    }
    public void deleteWords(New_...news){
       newsRepository.deleteNews();
    }
    public void getJson(String url){
       newsRepository.getJson(url);
    }
    

    }

    MainActivity
      
    package com.example.hotsearch;
    

    import androidx.appcompat.app.AppCompatActivity;
    import androidx.lifecycle.Observer;
    import androidx.lifecycle.ViewModelProviders;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;

    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;

    import com.google.gson.Gson;
    import com.google.gson.reflect.TypeToken;

    import java.io.ByteArrayOutputStream;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.List;

    public class MainActivity extends AppCompatActivity {
    Button buttonInsert,buttonClear,buttonNews;
    NewsViewModel newsViewModel;
    RecyclerView recyclerView;
    MyAdapter myAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

        final String[] url = {"你要访问的网络请求地址"};
        buttonInsert = findViewById(R.id.buttonInsert);
        buttonNews = findViewById(R.id.buttonNews);
        buttonClear = findViewById(R.id.button);
        recyclerView = findViewById(R.id.RecyclerView);
        myAdapter = new MyAdapter();
        newsViewModel = ViewModelProviders.of(this).get(NewsViewModel.class);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(myAdapter);
        newsViewModel.getJson(url[0]);
        newsViewModel.getAllNews().observe(this, new Observer<List<New_>>() {
            @Override
            public void onChanged(List<New_> new_s) {
                myAdapter.setAllNews(new_s);
                myAdapter.notifyDataSetChanged();
            }
        });
        buttonInsert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                New_ new_2 = new New_(400,"aaa");
                newsViewModel.insertWords(new_2);
            }
        });
        buttonClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                newsViewModel.deleteWords();
            }
        });
    

    // buttonNews.setOnClickListener(new View.OnClickListener() {
    // @Override
    // public void onClick(View v) {
    //
    // }
    // });

    }
    

    }

  • 相关阅读:
    Linux(Centos7)下redis5安装、部署、开机自启
    请求*.html后缀无法返回json数据的问题
    Linux搭建图片服务器减轻传统服务器的压力(nginx+vsftpd)
    Centos7和Centos6防火墙开放端口配置方法(避坑教学)
    分享一个酷炫动态登录页面html
    分布式全文搜索解决方案
    PHP实现支付宝登录
    PHP发送短信
    PHP中发送qq邮件
    ES6新语法(二)
  • 原文地址:https://www.cnblogs.com/yangxiao-/p/12740359.html
Copyright © 2020-2023  润新知