Android编程权威指南(第25章 HTTP与后台任务)

一.创建PhotoGallery应用
1.创建PhotoGallery项目

在这里插入图片描述
2.单击Next按钮,让应用向导创建一个名为PhotoGalleryActivity的空activity。
在这里插入图片描述
复制24章项目中的SingleFragmentActivity.java和activity_fragment.xml到当前项目中备用。
在这里插入图片描述
3.PhotoGalleryActivity.java的调整
输入以下代码

public class PhotoGalleryActivity extends SingleFragmentActivity {
    @Override
    protected Fragment creatFragment() {
        return PhotoGalleryFragment.newInsance();
    }
}

在这里插入图片描述
4.创建fragment_photo_gallery.xml文件
输入以下代码

<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/photo_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.bignerdranch.android.photogallery.PhotoGalleryActivity"/>

在这里插入图片描述
5.新建PhotoGalleryFragment.java
输入如下代码

public class PhotoGalleryFragment extends Fragment {
    private RecyclerView mPhtoRecyclerView;

    public static PhotoGalleryFragment newInstance() {
        return new PhotoGalleryFragment();
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_photo_gallery,container,false);

        mPhtoRecyclerView = (RecyclerView) v.findViewById(R.id.photo_recycler_view);
        mPhtoRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(),3));
        return v;
    }
}

在这里插入图片描述
6.新建FlickrFetchr.java
输入代码如下:

public class FlickrFetchr {
    public byte[] getUrlBytes(String urlSpec) throws IOException {
        URL url = new URL(urlSpec);
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        try{
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            InputStream in = connection.getInputStream();

            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                throw new IOException(connection.getResponseMessage() +
                        ":with" +
                        urlSpec);
            }
            int bytesRead = 0;
            byte[] buffer = new byte[1024];
            while ((bytesRead = in.read(buffer)) > 0) {
                out.write(buffer,0,bytesRead);
            }
            out.close();
            return out.toByteArray();
        }
        finally {
            connection.disconnect();
        }
    }
    public String getUrlString(String urlSpec) throws IOException {
        return new String(getUrlBytes(urlSpec));
    }
}

在这里插入图片描述
6.使用AsyncTask在后台线程上运行代码,在PhotoGalleryFragment.java中输入以下代码。

~~public class PhotoGalleryFragment extends Fragment {~~ 
    private static final String TAG = "PhotoGalleryFragment";
    ~~private RecyclerView mPhtoRecyclerView;~~ 
    ~~public static PhotoGalleryFragment newInstance() {
     return new PhotoGalleryFragment();~~ 
    ~~}
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);~~ 
        new FetchItemsTask().execute();
    ...
   private class FetchItemsTask extends AsyncTask<Void,Void,Void> {
        @Override
        protected Void doInBackground(Void...params) {
            try {
                String result = new FlickrFetchr()
                        .getUrlString("https://www.bignerdranch.com");
                Log.e(TAG, "Failed to fetch URL:", ioe);
            }
            return null;
        }
    }

7.线程与主线程,对FlickrFetchr.java添加一些常量
代码如下:

~~public class FlickrFetchr {~~ 
    private static final String TAG ="FlickrFetchr";
    private static final String API_KEY ="yourApiKeyHere";
    ...
      public void fetchItems() {
        try {
            String url = Uri.parse("https://api.flickr.com/services/rest")
                    .buildUpon()
                    .appendQueryParameter("method","flickr.photos.getRecent")
                    .appendQueryParameter("api_key",API_KEY)
                    .appendQueryParameter("format","json")
                    .appendQueryParameter("nojsoncallback","1")
                    .appendQueryParameter("extras","url_s")
                    .build().toString();
            String jsonString =getUrlString(url);
            Log.i(TAG,"Received JSON:" + jsonString);
        } catch (IOException ioe) {
            Log.e(TAG,"Failed to fetch items",ioe);
        }
    }

8.对PhotoGalleryFragment.java进行调整

    private class FetchItemsTask extends AsyncTask<Void,Void,Void> {
        @Override
        protected Void doInBackground(Void...params) {
            ~~try {
                String result = new FlickrFetchr()
                        .getUrlString("https://www.bignerdranch.com");
                Log.e(TAG, "Failed to fetch URL:", ioe);
            }~~ 
            new FlickrFetchr().fetchItems();
            return null;
        }

9.对GalleryItem.java创建模型对象类
代码如下:

    private String mCaption;
    private String mId;
    private String mUlr;
    
    @Override
    public String toString() {
        return mCaption;
    }

在这里插入图片描述
10.解析JSON数据(FlickrFetchr.java)
代码如下:

            ~~String jsonString =getUrlString(url);
            Log.i(TAG,"Received JSON:" + jsonString);~~ 
            JSONObject jsonBody = new JSONObject(jsonString);
        ~~} catch (IOException ioe) {
            Log.e(TAG,"Failed to fetch items",ioe);~~ 
        } catch (JSONException je){
            Log,e(TAG,"Failed to parse JSON", je);
        }

10.解析Flickr图片(FlickrFetchr.java)

            ~~Log,e(TAG,"Failed to parse JSON", je);
        }
    }~~ 
    private void parseItems(List<GalleryItem>items,JSONObject jsonBody)
        throws IOException,JSONException{
         
        JSONObject photosJsonObject = jsonBody.getJSONObject("photos");
        JSONArray photoJsonArray =photosJsonObject.getJSONArray("photo");
        
        for (int i =0;i< photoJsonArray.length();i++) {
            JSONObject photoJsonObject = photoJsonArray.getJSONObject(i);
            
            GalleryItem item =new GalleryItem();
            item.setId(photoJsonObject.getString("id"));
            item.setCaption(photoJsonObject.getString("title"));
            
            if (!photoJsonObject.has("url_s")) {
                continue;
            }
            
            item.setUrl(photoJsonObject.getString("url_s"));
            item.add(item);
        }

11.调用parseItems方法(FlickrFetchr.java)

     public ~~void~~  List<GalleryItem> fetchItems() {
        List<GalleryItem> items =new ArrayList<>();
            ~~JSONObject jsonBody = new JSONObject(jsonString);~~ 
            parseItems(items,jsonBody);
        ~~} catch (IOException ioe) {
            Log.e(TAG,"Failed to fetch items",ioe);
        } catch (JSONException je){
            Log,e(TAG,"Failed to parse JSON", je);
        }~~ 
        return items;

12.从AsyncTask回到主线程(PhotoGalleryFragment.java)

        ~~return v;~~ 

    }
    private class PhotoHolder extends RecyclerView.ViewHolder {
        private TextView mTitleTextView;
        
        public PhotoHolder(View itemView){
            super(itemView);
            
            mTitleTextView =(TextView) itemView;
        }
        public void bindGalleryItem(GalleryItem item) {
            mTitleTextView.setText(item.toString());
          ~~public void bindGalleryItem(GalleryItem item) {
            mTitleTextView.setText(item.toString());
        }
    }~~  
    private class PhotoAdapter extends RecyclerView.Adapter<PhotoHolder> {
        private List<GalleryItem> mGalleryItems;
        
        public PhotoAdapter(List<GalleryItem> galleryItems) {
            mGalleryItems = galleryItems;
        }
        @Override
        public PhotoHolder onCreateViewHolder(ViewGroup viewGroup,int viewType) {
            TextView textView=new TextView(getActivity());
            return new PhotoHolder(textView);
        }
        
        @Override
        public void onBindViewHolder(PhotoHolder photoHolder,int position) {
            GalleryItem galleryItem=mGalleryItems.get(position);
            photoHolder.bindGalleryItem(galleryItem);
        }
        @Override
        public int getItemCount() {
            return mGalleryItems.size();
        }

13.实现setupAdapter方法(PhotoGalleryFragment.java)

    ~~private static final String TAG = "PhotoGalleryFragment";
    private RecyclerView mPhtoRecyclerView;~~ 
    private List<GalleryItem>mItems =new ArrayList<>();

            setupAdapter();
        ~~return v;~~ 

    }
    private void setupAdapter() {
        if (isAdded()) {
            mPhtoRecyclerView.setAdapter(new PhotoAdapter(mItems));
        }
    }

14.添加adapter更新代码(PhotoGalleryFragment.java)

 private class FetchItemsTask extends AsyncTask<Void,Void,~~void~~ list<GalleryItem>> {
        @Override
        protected ~~void~~ List<GalleryItem> doInBackground(Void...params) {
        return new FlickrFetchr().fetchItems();
        ~~return null;~~ 
        }
        @Override
        protected void onPostExecute(List<GalleryItem> items) {
            mItems =items;
            setupAdapter();
        }
注:由于学习要求,本教程好多都用到前面章节的一些设置,所以好多文件会出错,结果就出不来,所以本人就不发布结果出来了。

成功之后的结果大致为这样
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值