Android之JSON数据解析(AsyncTask异步加载)

看下运行结果

数据接口api! http://json.cn/#一个工具网址

下面看下如何实现的

第一步:打 开activity_main布局,添加一个ListView

<ListView
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:id="@+id/listViwe"
></ListView>

第二步:添加一个子布局Iitem_layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
<ImageView
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:id="@+id/ItemImag"
    />
<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_gravity="center"
        >
        <TextView
            android:maxLines="1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/ItemTitle"
            android:text="我是标题"
            android:textSize="15dp"
            />
        <TextView
            android:maxLines="3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/ItemContext"
            android:text="我是内容"
            android:textSize="10dp"

            />
 </LinearLayout>
</LinearLayout>

第三步:创建一个Java类,命名为NewsBen

public class NewsBen {
    public String NewsIcon;//url是String类型的
    public String NewsTitle;
    public String NewsContext;
}

第四步:对MainAcitvity进行编写

public class MainActivity extends AppCompatActivity {

    private ListView mListView;
   // 原生API网址
    private static String url=
            "http://www.imooc.com/api/teacher?type=4&num=30";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //实例化对象
        mListView= (ListView) findViewById(R.id.listView);
        //new一个类,并启动url
        new NewsAsyncTask().execute(url);
    }
    
       //AsyncTask<String,Void,List<NewsBen>>\
       //第一个参数:是传递过来的url(j是String类型)
       //第二个参数:表示是进度条的进度。这里我们不需要所以为Void
      // 第三个参数:表示返回的是List<NewsBen>集合
     
    class NewsAsyncTask extends AsyncTask<String,Void,List<NewsBen>>{


        /**实现网络的异步访问*/
        @Override
        protected List<NewsBen> doInBackground(String... strings) {
            //将url传递给了getJsonData()方法
            return getJsonData(strings[0]);
        }

        /**将我们生成的NewsBen设置给我们的ListView*/
        @Override
        protected void onPostExecute(List<NewsBen> newsBens) {
            super.onPostExecute(newsBens);
            //数据:通过doInBackground方法所返回来的newsBens!这里要创建一个NewsAdapter类的适配器
            NewsAdapter adapter=new NewsAdapter(MainActivity.this,newsBens);
            mListView.setAdapter(adapter);
        }

        /**将URL对应的JSON格式数据转化为我们所封装的NewBen*/
        private List<NewsBen> getJsonData(String url) { //传递过来的url地址
            List<NewsBen> newBeanList=new ArrayList<>();
            try {
                /**new URL(url).openStream():可根据URL直接联网获取网络数据,返回值应为InputStream*/
               //获取JSON格式的字符串,在此之前要把URL原生api转化格式,转换成我我们能够识别的数据!这里要调用readStream方法了
                String jsonString=readStream(new URL(url).openStream());//打开网址
                Log.d("xys",jsonString);
                JSONObject jsonObject;
                NewsBen newBen;
                /**
                   1.sonString就是将原生的API传递过来,并创建一个JSONObject
                   这里说个小技巧哈!就是呢看到“{”就是创建一个JSONObject;
                    看到“[”就是要创建一个JSONArray
                 */
                //看到一个{就创建JSONObject
                jsonObject=new JSONObject(jsonString);
                //从jsonObject中获取data这个数组
                JSONArray jsonArray=jsonObject.getJSONArray("data");
                
                for (int i=0;i<jsonArray.length();i++){
                     //从jsonArray数组中获取到每一个jsonObject对象
                    jsonObject=jsonArray.getJSONObject(i);
                    newBen=new NewsBen();
                    //获取到api中的每一个数据赋值给newsBen中的每一项
                    newBen.newsIconUrl=jsonObject.getString("picSmall");
                    newBen.newsTitle=jsonObject.getString("name");
                    newBen.newsContext=jsonObject.getString("description");
                    //把newsBen中的数据全部放到newsList集合中去
                    newBeanList.add(newBen);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
             //把这个集合返回给doInBackground()中去!在这里可以打一个断点,测试下这个集合中有没有30个值
            return newBeanList;
        }

         /**通过InputStream(is)获取我们所需要的信息也就是解析网页返回的数据 * */
        private String readStream(InputStream is){
            //获取JSON格式的字符串要读取通过url通过InputStream返回的字符串信息
            InputStreamReader isr;
            String result="";
            //从InputStreamReader中一行一行的去读
            try {
                //让我们来每一行的去读
                String line="";
                //将字节流转化为字符流
                isr=new InputStreamReader(is,"utf-8");
                BufferedReader br=new BufferedReader(isr);
                //读取JSON字符串
                while ((line=br.readLine())!=null){
                    result+=line;
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return  result;
        }

    }
}

第五步:创建一个NewsAdapter类

public class NewsAdapter extends BaseAdapter {
    
    private List<NewsBen> mList;
   //加载布局
    private LayoutInflater mLayout;
   //来个构造方法 
    NewsAdapter(Context context,List<NewsBen> data){
        mList=data;
        mLayout=LayoutInflater.from(context);
    }
    //下面就不解释了!
    @Override
    public int getCount() {
        return mList.size();
    }

    @Override
    public Object getItem(int i) {
        return mList.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolde viewHolde;
        if (view==null){
            viewHolde=new ViewHolde();
            //加载item_layout布局
            view=mLayout.inflate(R.layout.item_layout,null);
            对ViewHolder对象进行实例化
            viewHolde.ivIcon= (ImageView) view.findViewById(R.id.ItemIco);
            viewHolde.tv_Title= (TextView) view.findViewById(R.id.ItemTitle);
            viewHolde.tv_Context= (TextView) view.findViewById(R.id.ItemContext);
            view.setTag(viewHolde);
        }else {
            viewHolde= (ViewHolde) view.getTag();
        }
        //因为url是String类型的无法直接获取图片!所以要进行编辑
        viewHolde.ivIcon.setImageResource(R.mipmap.ic_launcher);
        //获取mList集合中的newsIconUrl赋值给url
        String url=mList.get(i).newsIconUrl;
        viewHolde.ivIcon.setTag(url);
        //调用ImageIcon类中的showImageAsyncTask()来获取图片
        new ImageIcon().showImageAsyncTask(viewHolde.ivIcon,url);
        //从mList集合中获取值
        viewHolde.tv_Title.setText(mList.get(i).newsTitle);
        viewHolde.tv_Context.setText(mList.get(i).newsContext);
        return view;
    }
    class ViewHolde{
        public ImageView ivIcon;
        public TextView tv_Title;
        public TextView tv_Context;
    }
}

第六步:获取网络图片


public class ImageIcon {
    
    //创建一个方法
    public void showImageAsyncTask(ImageView imageView,String url){
        //创建一个对象并实例化它
        NewsAdapter newsAdapter=  new NewsAdapter(imageView);
        newsAdapter.execute(url);//启动从NewsAdapte中传递过来的url
    }
    private class NewsAdapter extends AsyncTask<String,Void,Bitmap>{
        private ImageView mImageView;
        public NewsAdapter(ImageView imageView){
            mImageView=imageView;
        }
        @Override
        protected Bitmap doInBackground(String... strings) {
            //传递url对象并调用getBitmapFromURL方法
            return getBitmapFromURL(strings[0]);
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            //对图片进行赋值
            mImageView.setImageBitmap(bitmap);
        }
    }
    /** 我们获取一个Bitmap是通过URL获取的,用于同一个URL获取一个Bitmap*/
    public Bitmap getBitmapFromURL(String urlString){
        Bitmap bitmap;
        InputStream is = null;
        try {
            URL url=new URL(urlString);
            HttpURLConnection connection= (HttpURLConnection) url.openConnection();
            //获取InputStream对象
            is=new BufferedInputStream(connection.getInputStream());
            bitmap= BitmapFactory.decodeStream(is);
            //将资源释放
            connection.disconnect();
            return bitmap;
        } catch (java.io.IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

到这就结束了!希望对大家有帮助~

最后运行时不要忘了在配置清单中加一个网络访问权限

<uses-permission android:name="android.permission.INTERNET"/>
posted @ 2017-09-26 09:00  陌上花开222  阅读(318)  评论(0编辑  收藏  举报