-2

此代码使用来自 Web 上的 JSON 和 LazyAdapter 的数据更新 2 ListView 将图像从 URL 转换并放在 ListView 上,在 2.3 上工作正常,但在 Android 4.0 上不起作用。

这是代码

EventosActivity.java

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

    hojeLista = new ArrayList<HashMap<String, String>>();
    proximosLista = new ArrayList<HashMap<String, String>>();


    new LoadEventos().execute();

}

/**
 * Background Async Task to Load all product by making HTTP Request
 * */
class LoadEventos extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(EventosActivity.this);
        pDialog.setMessage("Dando uma olhada aqui, peraê...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
    }

    /**
     * getting All evento from url
     * */
    protected String doInBackground(String... args) {
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        // getting JSON string from URL
        JSONObject json = jParser.makeHttpRequest(url_hoje, "GET", params);
        JSONObject json2 = jParser.makeHttpRequest(url_proximos, "GET", params);

        try {
            // Checking for SUCCESS TAG
            int success = json.getInt(TAG_SUCCESS);
            int success2 = json2.getInt(TAG_SUCCESS);

            if (success == 1) {
                // evento found
                // Getting Array of Products
                evento = json.getJSONArray(TAG_EVENTO);

                // looping through All Products
                for (int i = 0; i < evento.length(); i++) {
                    JSONObject c = evento.getJSONObject(i);


                    // Storing each json item in variable
                    String id = c.getString(TAG_ID);
                    String titulo = c.getString(TAG_TITULO);
                    String local_nome = c.getString(TAG_LOCAL_NOME);
                    String data = c.getString(TAG_DATA);
                    String imagem = c.getString(TAG_IMAGEM);

                    //if ("16".equals(TAG_CLASSIFICACAO)) { }


                    // creating new HashMap
                    HashMap<String, String> map = new HashMap<String, String>();


                    // adding each child node to HashMap key => value
                    map.put(TAG_ID, id);
                    map.put(TAG_TITULO, titulo);
                    map.put(TAG_LOCAL_NOME, local_nome);
                    map.put(TAG_DATA, data);
                    map.put(TAG_IMAGEM, imagem);

                    // adding HashList to ArrayList
                    hojeLista.add(map);

                }
            }

            if (success2 == 1) {
                // evento found
                // Getting Array of Products
                evento = json2.getJSONArray(TAG_EVENTO);

                // looping through All Products
                for (int i = 0; i < evento.length(); i++) {
                    JSONObject c2 = evento.getJSONObject(i);


                    // Storing each json item in variable
                    String id = c2.getString(TAG_ID);
                    String titulo = c2.getString(TAG_TITULO);
                    String local_nome = c2.getString(TAG_LOCAL_NOME);
                    String data = c2.getString(TAG_DATA);
                    String imagem = c2.getString(TAG_IMAGEM);

                    //if ("16".equals(TAG_CLASSIFICACAO)) { }


                    // creating new HashMap
                    HashMap<String, String> map2 = new HashMap<String, String>();


                    // adding each child node to HashMap key => value
                    map2.put(TAG_ID, id);
                    map2.put(TAG_TITULO, titulo);
                    map2.put(TAG_LOCAL_NOME, local_nome);
                    map2.put(TAG_DATA, data);
                    map2.put(TAG_IMAGEM, imagem);

                    // adding HashList to ArrayList
                    proximosLista.add(map2);

                }
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }


        return null;
    }



    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        // dismiss the dialog after getting all evento

        pDialog.dismiss();  

        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {

                ListView list = (ListView)findViewById(android.R.id.list);
                ListView list2 = (ListView)findViewById(R.id.lvProximos);
           ks.     
                LazyAdapter adapter=new LazyAdapter(EventosActivity.this, hojeLista);
                list.setAdapter(adapter);

                LazyAdapter adapter2=new LazyAdapter(EventosActivity.this, proximosLista);
                list2.setAdapter(adapter2);



                list.setOnItemClickListener(new OnItemClickListener() {

                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                            int position, long id) {
                        String id2 = ((TextView) view.findViewById(R.id.id)).getText().toString();

                        Intent in = new Intent(getApplicationContext(), EventoDetalheActivity.class);

                        in.putExtra(TAG_ID, id2);

                        startActivityForResult(in, 100);
                    }
                });

                list2.setOnItemClickListener(new OnItemClickListener() {

                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                            int position, long id) {
                        String id2 = ((TextView) view.findViewById(R.id.id)).getText().toString();

                        Intent in = new Intent(getApplicationContext(), EventoDetalheActivity.class);

                        in.putExtra(TAG_ID, id2);

                        startActivityForResult(in, 100);
                    }
                });
            }
        });

    }

}}

LazyAdapter.java

public class LazyAdapter extends BaseAdapter {
private Context activity;
private ArrayList<HashMap<String, String>> data;
private LayoutInflater inflater=null;
//public ImageLoader imageLoader; 
private URL url;
private Bitmap bmp;
public LazyAdapter(Context a, ArrayList<HashMap<String, String>> d) {
    activity = a;
    data=d;
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    //imageLoader=new ImageLoader(activity.getApplicationContext());
}

public int getCount() {
    return data.size();
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
    View vi=convertView;
    if(convertView==null)
        vi = inflater.inflate(R.layout.eventoitem, null);
    TextView id = (TextView)vi.findViewById(R.id.id); 
    TextView titulo = (TextView)vi.findViewById(R.id.titulo); 
    TextView local_nome = (TextView)vi.findViewById(R.id.local_nome);
    TextView data0 = (TextView)vi.findViewById(R.id.data);
    ImageView im=(ImageView)vi.findViewById(R.id.imgImagem);

    HashMap<String, String> evento = new HashMap<String, String>();
    evento = data.get(position);

    // Setting all values in listview
    id.setText(evento.get("id"));
    titulo.setText(evento.get("titulo"));
    local_nome.setText(evento.get("local_nome"));
    data0.setText(evento.get("data"));

    try {
        url = new URL(evento.get("imagem"));
         bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
           im.setImageBitmap(bmp);
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    return vi;
}

}

谢谢你帮助我。

4

3 回答 3

2

问题出在您的 getView 方法上,该方法在 UI 线程上运行,但您调用了一些使用互联网的东西。这是有问题的电话:

bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
       im.setImageBitmap(bmp);

对于某个版本的android(据我所知是蜂窝),这是不允许的,因为互联网使用可能需要一段时间,你不应该让用户界面等待它完成。

您找到了它是一件好事,因为如果设备上的互联网速度太慢而没有任何崩溃,它可能会导致 ANR。

解决它的一种方法是对每个视图使用 ViewHolder,它还将包括一个用于加载图像的 asyncTask,并在完成后将其设置为相关的 ImageView。如果 viewHolder 已经有一个任务,它应该被取消,因为它属于不再可见的东西。如果需要,您还可以添加缓存机制。

一般来说,如果你怀疑某个函数可能会运行很长时间(比如超过 1 秒),你应该让它在后台运行(或尝试真正改进它)而不是让 UI 线程处理它。原因是你会得到一个非流畅的应用程序,如果你让这个函数运行大约 5 秒左右,你也会得到一个 ANR。

于 2013-03-26T20:50:22.623 回答
0

当您尝试从主 UI 线程进行网络相关操作时,会发生 NetworkOnMainThreadException。你应该在后台线程上做同样的事情,比如 asynctask。

在您的 getview 中,您正在下载位图。

bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
   im.setImageBitmap(bmp);

我同意安卓开发者。

您还应该使用来自 listview 的 viewholder。 http://developer.android.com/training/improving-layouts/smooth-scrolling.html

http://www.youtube.com/watch?v=wDBM6wVEO70。该视频对 Viewholder 和 listview 有很好的解释。

我建议您使用通用图像加载器。

延迟列表是使用 url 从 sdcard 或 fomr 服务器延迟加载图像。这就像按需加载图像。

图像可以缓存到本地sd卡或手机内存。Url 被认为是关键。如果密钥存在于 sdcard 中,则显示来自 sd 卡的图像,否则通过从服务器下载显示图像并将其缓存到您选择的位置。可以设置缓存限制。您还可以选择自己的位置来缓存图像。缓存也可以清除。

而不是用户等待下载大图像然后显示惰性列表按需加载图像。由于图像区域缓存,您可以离线显示图像。

https://github.com/thest1/LazyList。懒惰列表

在你的 getview

imageLoader.DisplayImage(imageurl, imageview);
ImageLoader Display method

public void DisplayImage(String url, ImageView imageView) //url and imageview as parameters
{
imageViews.put(imageView, url);
Bitmap bitmap=memoryCache.get(url);   //get image from cache using url as key
if(bitmap!=null)         //if image exists
    imageView.setImageBitmap(bitmap);  //dispaly iamge
 else   //downlaod image and dispaly. add to cache.
 {
    queuePhoto(url, imageView);
    imageView.setImageResource(stub_id);
 }
 }

惰性列表的替代方法是通用图像加载器

https://github.com/nostra13/Android-Universal-Image-Loader。它基于惰性列表(工作原理相同)。但它还有很多其他配置。我更喜欢使用Universal Image Loader,因为它为您提供了更多配置选项。如果下载失败,您可以显示错误图像。可以显示带圆角的图像。可以缓存在磁盘或内存上。可以压缩图像。

在您的自定义适配器构造函数中

 File cacheDir = StorageUtils.getOwnCacheDirectory(context, "your folder");

 // Get singletone instance of ImageLoader
 imageLoader = ImageLoader.getInstance();
 // Create configuration for ImageLoader (all options are optional)
 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
      // You can pass your own memory cache implementation
     .discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
     .discCacheFileNameGenerator(new HashCodeFileNameGenerator())
     .enableLogging()
     .build();
 // Initialize ImageLoader with created configuration. Do it once.
 imageLoader.init(config);
 options = new DisplayImageOptions.Builder()
 .showStubImage(R.drawable.stub_id)//display stub image
 .cacheInMemory()
 .cacheOnDisc()
 .displayer(new RoundedBitmapDisplayer(20))
 .build();

在你的 getView()

 ImageView image=(ImageView)vi.findViewById(R.id.imageview); 
 imageLoader.displayImage(imageurl, image,options);//provide imageurl, imageview and options
于 2013-03-26T20:57:22.947 回答
0

出于显而易见的原因,不建议这样做,但您可以将其添加到您的课程中:

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build() 
StrictMode.setThreadPolicy(policy); 
于 2013-03-26T21:07:50.417 回答