-2

このコードは、Web上のJSONからのデータで2 ListViewを更新し、LazyAdapterはURLから画像を変換してListViewに配置します。2.3では正常に動作しますが、Android4.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

問題は、UIスレッドで実行されるgetViewメソッドにありますが、インターネットを使用するものを呼び出しています。問題のある呼び出しは次のとおりです。

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

アンドロイドの特定のバージョン(私が覚えている限りではハニカム)の時点では、インターネットの使用に時間がかかる可能性があり、UIが終了するのを待たないようにする必要があるため、これは許可されていません。

それはあなたがそれを見つけた良いことです、それはそれがクラッシュなしで動作したデバイスでインターネットが遅すぎる場合にANRを引き起こす可能性があるからです。

これを解決する1つの方法は、ビューごとにViewHolderを使用することです。これには、画像をロードし、完了時に関連するImageViewに設定するためのasyncTaskも含まれます。viewHolderにすでにタスクがある場合は、表示されなくなったものに属していたため、キャンセルする必要があります。必要に応じて、キャッシュメカニズムを追加することもできます。

一般に、特定の関数が長時間(たとえば、1秒以上)実行される可能性があると思われる場合は、UIスレッドに処理させるのではなく、バックグラウンドで実行する(または実際に改善する)必要があります。その理由は、非流動的なアプリを取得し、関数を約5秒間実行すると、ANRも取得するためです。

于 2013-03-26T20:50:22.623 に答える
0

NetworkOnMainThreadExceptionは、メインUIスレッドからネットワークを実現する操作を実行しようとしたときに発生します。asynctaskのようなバックグラウンドスレッドでも同じことを行う必要があります。

getviewで、ビットマップをダウンロードしています。

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

私はAndroid開発者に同意します。

また、listviewのビューホルダーを使用する必要があります。 http://developer.android.com/training/improving-layouts/smooth-scrolling.html

http://www.youtube.com/watch?v=wDBM6wVEO70。ビデオには、ビューホルダーとリストビューに関する優れた説明があります。

UniversalImageLoaderを使用することをお勧めします。

遅延リストは、URLを使用してSDカードまたはFOMRサーバーから画像を遅延読み込みすることです。これは、オンデマンドで画像を読み込むようなものです。

画像はローカルのSDカードまたは電話のmmeoryにキャッシュできます。URLがキーと見なされます。キーがsdカードに存在する場合は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。これはレイジーリストに基づいています(同じ原理で動作します)。しかし、他にもたくさんの構成があります。より多くの構成オプションを提供するUniversalImageLoadercozを使用したいと思います。ダウンロードに失敗した場合は、エラー画像を表示できます。角が丸い画像を表示できます。ディスクまたはメモリにキャッシュできます。画像を圧縮できます。

カスタムアダプターコンストラクターで

 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 に答える