0

我已经制作了从 json 获取图像路径的 gridview 应用程序。它可以找到但是当它加载时它很慢。我试图找到解决方案,他们建议我使用 ViewHolder,但我不知道如何在我的 gridview 应用程序中使用。

如何在我的应用程序中使用 ViewHolder?我如何加快我的申请?

这段代码可以找到,但加载速度很慢。

public class MainActivity extends Activity {

String strUrl = "http://192.168.10.104/adchara1/";
GridView gridView;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Creating a new non-ui thread task to download json data
    DownloadTask downloadTask = new DownloadTask();

    // Starting the download process
    downloadTask.execute(strUrl);

    gridView = (GridView) findViewById(R.id.lv_countries);        
    gridView.setOnItemClickListener(new OnItemClickListener() {

        public void onItemClick(AdapterView<?> parent, View v, int positon,
                long id) {

             HashMap<String, Object> hm = (HashMap<String, Object>) gridView.getAdapter().getItem(positon);
             String imgPath = (String) hm.get("photo"); //get downloaded image path
             Intent i = new Intent(MainActivity.this, DisplayActivity.class); //start new Intent to another Activity.
             i.putExtra("ClickedImagePath", imgPath ); //put image link in intent.
             startActivity(i);
        }
    });
}

/** A method to download json data from url */
private String downloadUrl(String strUrl) throws IOException{
  String data = "";
  InputStream iStream = null;

    HttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(strUrl);
    ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();
    try {
        httpPost.setEntity(new UrlEncodedFormEntity(param));
        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        iStream = httpEntity.getContent();
    } catch (Exception e) {
        Log.e("log_tag", "Error in http connection " + e.toString());
    }
    try {
        BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
        StringBuilder sb = new StringBuilder();
        String line = "";
        while((line = br.readLine()) != null){
            sb.append(line + "\n");
        }
        iStream.close();
        data = sb.toString();
    } catch (Exception e) {
        Log.e("log_tag", "Error converting result " + e.toString());
    }
    return data;
}

/** AsyncTask to download json data */
private class DownloadTask extends AsyncTask<String, Integer, String>{
    String data = null;
    @Override
    protected String doInBackground(String... url) {
        try{
            data = downloadUrl(url[0]);
        }catch(Exception e){
            Log.d("Background Task",e.toString());
        }
        return data;
    }

    @Override
    protected void onPostExecute(String result) {

        // The parsing of the xml data is done in a non-ui thread
        GridViewLoaderTask gridViewLoaderTask = new GridViewLoaderTask();

        // Start parsing xml data
        gridViewLoaderTask.execute(result);
    }
}

/** AsyncTask to parse json data and load ListView */
private class GridViewLoaderTask extends AsyncTask<String, Void, SimpleAdapter>{

    JSONObject jObject;
    // Doing the parsing of xml data in a non-ui thread
    @Override
    protected SimpleAdapter doInBackground(String... strJson) {
        try{
            jObject = new JSONObject(strJson[0]);
            CountryJSONParser countryJsonParser = new CountryJSONParser();
            countryJsonParser.parse(jObject);
        }catch(Exception e){
            Log.d("JSON Exception1",e.toString());
        }

        // Instantiating json parser class
        CountryJSONParser countryJsonParser = new CountryJSONParser();

        // A list object to store the parsed countries list
        List<HashMap<String, Object>> countries = null;

        try{
            // Getting the parsed data as a List construct
            countries = countryJsonParser.parse(jObject);
        }catch(Exception e){
            Log.d("Exception",e.toString());
        }

        // Keys used in Hashmap
        String[] from = { "frame","photo"};

        // Ids of views in listview_layout
        int[] to = { R.id.iv_frame,R.id.iv_photo};

        // Instantiating an adapter to store each items
        // R.layout.listview_layout defines the layout of each item
        SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), countries, R.layout.lv_layout, from, to);
        return adapter;
    }

    /** Invoked by the Android on "doInBackground" is executed */
    @Override
    protected void onPostExecute(SimpleAdapter adapter) {

        // Setting adapter for the listview
        gridView.setAdapter(adapter);

        for(int i=0;i<adapter.getCount();i++){
            HashMap<String, Object> hm = (HashMap<String, Object>) adapter.getItem(i);
            String frameUrl = (String) hm.get("frame_path");
            String imgUrl = (String) hm.get("photo_path");
            ImageLoaderTask imageLoaderTask = new ImageLoaderTask();

            HashMap<String, Object> hmDownload = new HashMap<String, Object>();
            hm.put("frame_path", frameUrl);
            hm.put("photo_path",imgUrl);
            hm.put("position", i);

            // Starting ImageLoaderTask to download and populate image in the listview
            imageLoaderTask.execute(hm);
        }
    }
} 

    /** AsyncTask to download and load an image in ListView */
    private class ImageLoaderTask extends AsyncTask<HashMap<String, Object>, Void, HashMap<String, Object>>{

        @Override
        protected HashMap<String, Object> doInBackground(HashMap<String, Object>... hm) {

            InputStream iStream = null;
            String imgUrl;
            String frameUrl;
            imgUrl = (String) hm[0].get("photo_path");
            frameUrl = (String) hm[0].get("frame_path");
            int position = (Integer) hm[0].get("position");

            URL url;
            URL urlFrame;
            try {
                url = new URL(imgUrl);
                urlFrame = new URL(frameUrl);
                // Creating an http connection to communicate with url
                HttpURLConnection urlConnection = (HttpURLConnection) url
                        .openConnection();

                // Connecting to url
                urlConnection.connect();

                // Reading data from url
                iStream = urlConnection.getInputStream();

                // Getting Caching directory
                File cacheDirectory = getBaseContext().getCacheDir();

                // Temporary file to store the downloaded image
                File tmpFile = new File(cacheDirectory.getPath() + "/wpta_"+ position + ".png");

                // The FileOutputStream to the temporary file
                FileOutputStream fOutStream = new FileOutputStream(tmpFile);

                // Creating a bitmap from the downloaded inputstream
                Bitmap b = BitmapFactory.decodeStream(iStream);

                // Writing the bitmap to the temporary file as png file
                b.compress(Bitmap.CompressFormat.PNG, 100, fOutStream);

                // Flush the FileOutputStream
                fOutStream.flush();

                // Close the FileOutputStream
                fOutStream.close();

                // Create a hashmap object to store image path and its position in the listview
                HashMap<String, Object> hmBitmap = new HashMap<String, Object>();

                // Storing the path to the temporary image file
                hmBitmap.put("photo", tmpFile.getPath());
                hmBitmap.put("frame", tmpFile.getPath());

                // Storing the position of the image in the listview
                hmBitmap.put("position", position);

                // Returning the HashMap object containing the image path and position
                return hmBitmap;
            } catch (MalformedURLException e) {
                return null;
            } catch (FileNotFoundException e) {
                return null;
            } catch (IOException e) {
                return null;
            }
        }

    @Override
    protected void onPostExecute(HashMap<String, Object> result) {
        // Getting the path to the downloaded image
        String path = (String) result.get("photo");
        String framePath = (String) result.get("frame");
        // Getting the position of the downloaded image
        int position = (Integer) result.get("position");

        // Getting adapter of the listview
        SimpleAdapter adapter = (SimpleAdapter ) gridView.getAdapter();

        // Getting the hashmap object at the specified position of the listview
        HashMap<String, Object> hm = (HashMap<String, Object>) adapter.getItem(position);

        // Overwriting the existing path in the adapter
        hm.put("photo",path);
        hm.put("frame", framePath);
        // Noticing listview about the dataset changes
        adapter.notifyDataSetChanged();
    }
}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

}

4

2 回答 2

0

您应该阅读此处的幻灯片以提高性能。它包含使用 ViewHolder 的示例。

于 2012-10-26T03:05:19.377 回答
0

看看我们在 Google I/O 2010 上的 Google Guys。他们在 Android 团队中有一个由谷歌软件工程师主持的会议,讨论了 ListView 和相关的东西,包括如何使用 ViewHolder 类优化 listview 的使用。我想你可以从中学到一些东西。这是链接Google I/O 2010 - ListView Session

于 2012-10-26T04:19:14.210 回答