0

複数のアイテムを持つリストビューがあり、すべてのアイテムに2つのボタンがあります。私がやりたいのは、ボタンをクリックすると、HttpPost を介してサーバーにデータが送信されることです。Adapter.getView() 内にスレッドを配置しましたが、アダプターが非同期スレッドに既にあるため、機能しません。どうすればそれを機能させることができるか考えていますか?

私のリストビュー:

// ... OnCreate ListView ...
// ... new ListAppTask().execute();
// ...
public class ListAppTask extends AsyncTask<Void, Void, List<ProductExtended>> {

    protected List<ProductExtended> doInBackground(Void... args) {
        Product product = new Product();
        List<ProductExtended> products = product.getLastProducts(getApplicationContext());

        return products;
    }

    protected void onPostExecute(List<ProductExtended> result) {
        data.addAll(result);
        adapter.notifyDataSetChanged();
        if (progressDialog != null) {
            progressDialog.dismiss();
            progressDialog = null;
        }
    }
}

私のアダプター:

    public class PackageAdapter extends BaseAdapter {

        private List<ProductExtended> data;
        private Context context;

        public PackageAdapter(Context context, List<ProductExtended> data) {
            this.context = context;
            this.data = data;
        }

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

        @Override
        public ProductExtended getItem(int position) {
            return data.get(position);
        }

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

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            final ProductExtended item = getItem(position);
            ViewHolder holder;
            if (convertView == null) {
                LayoutInflater li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = li.inflate(R.layout.package_row, parent, false);
                holder = new ViewHolder();
                holder.btnBa = (LinearLayout) convertView.findViewById(R.id.idBonneaffaire);
                holder.btnJl = (LinearLayout) convertView.findViewById(R.id.idJelai);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }


            holder.btnBa.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                        new Thread() {

                            @Override
                            public void run() {
                                // ---------------- PROBLEM HERE -------------------
                                HttpClient httpclient = new DefaultHttpClient();
                                HttpPost httppost = new HttpPost("My URL");
                                // Execute HTTP Post Request
                                try {
                                    HttpResponse response = httpclient.execute(httppost);
                                    String reponse = EntityUtils.toString(response.getEntity());

                                } catch (UnknownHostException e) {
                                } catch (HttpHostConnectException e) {
                                } catch (ClientProtocolException e) {
                                } catch (IOException e) {
                                }
                            }
                        }.start();
                }
            });

          // Same for the second LinearLayout considered as Button



            return convertView;
        }

        static class ViewHolder {
            LinearLayout btnBa;
            LinearLayout btnJl;
        }

そして、エラーが表示されました:

Only the original thread that created a view hierarchy can touch its views. adapter

ありがとう、アクラム

4

2 に答える 2

1

私は物事をシンプルに保つことを好みます。ThreadHandlerはそれぞれ Java と Android の重要な概念ですが、UI イベントに応答して http を実行することは Android では非常に一般的であり、AsyncTaskという驚くべきヘルパーが発明されました。

囲んでいる Activity クラスへの内部参照を使用して、このクラスの匿名インスタンスを作成します (つまり、実際には、アクティビティ内でクラスを定義し、作成しないでくださいstatic)。開発者が Android UI とスレッド パターンを設計する際に念頭に置いていたのは、この種の Java の機能です。

上記のドキュメントから:

非同期タスクが実行されると、タスクは...

doInBackground(Params...)、実行が終了した直後にバックグラウンド スレッドで呼び出されます。onPreExecute()このステップは、時間がかかる可能性のあるバックグラウンド計算を実行するために使用されます。...

onPostExecute(Result)、バックグラウンド計算が終了した後にUI スレッドで呼び出されます。バックグラウンド計算の結果は、パラメーターとしてこのステップに渡されます。

[余分な詳細は省きました。これも私の強調点です]。

アダプターgetViewは非同期タスクを参照する必要があります。非同期タスクは、すべての同期 http 要求を使用して実行されたコード ブロックからの情報を UI スレッドから渡し、そのビューを操作するために使用できる UI スレッド上のコード ブロックに渡します (リストビューはこちら)。

注意:タスクが終了した後もリストビューがそのデータに関連していることを確認することを忘れないでください。そうしないと、AbsListViewビューのリサイクルのために、データを明らかに間違ったセルに入れる危険があります。

一番、

トム。

于 2013-07-01T22:56:21.350 に答える