0

次のようなクラスファイルがあります。

public class Search_Results extends SherlockListActivity{

     String result = "";
     SearchView searchView;
     Context context = this;
     private Intent intent = null;
     private String searchThis = "";

      @Override
      protected void onCreate(Bundle savedInstanceState){
             super.onCreate(savedInstanceState);
             setTheme(R.style.Sherlock___Theme_DarkActionBar);
             setContentView(R.layout.search_results);
             ListView myList=(ListView)findViewById(android.R.id.list);
             ProgressBar progress = (ProgressBar)findViewById(R.id.progress_spin);
             intent = getIntent();
             searchThis = intent.getStringExtra(Home.SEARCH_SERVICE);
             new Retrieve(context, progress, searchThis, myList).execute("");
      }//onCreate
}

Retrieve()これは、別の Java ファイルにあるnew を呼び出して拡張しますAsyncTask

public class Retrieve extends AsyncTask <String, Integer, ArrayList<String>>{

     private Context context;
     private String title = "";
     private ArrayList<String> list = null;
     private ArrayList<NameValuePair> nameValuePairs = null;
     private String result = "";
     private ProgressBar progress;
     private String searchThis;
     private ListView mylist;

     //constructor
     public Retrieve(Context context, ProgressBar progress, String searchThis, ListView myList) {
         this.context = context;
         this.progress = progress;
         this.searchThis = searchThis;
         this.mylist = myList;
     }
protected ArrayList<String> doInBackground(String... params){
            progress.setVisibility(View.VISIBLE);
            InputStream is = null;
            list = new ArrayList<String>();
            nameValuePairs = new ArrayList<NameValuePair>();
            nameValuePairs.add(new BasicNameValuePair("searchThis", searchThis));
            try{
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(URL);
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();
            }
            catch(Exception e){
                Log.e("CONNECTION_ERROR", "Error in http connection "+e.toString());
            }
            try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null){
                    sb.append(line + "\n");
                }
                is.close();
                result=sb.toString();
            }
            catch(Exception e){
                Log.e("BUFFER_ERROR", "Error converting result "+e.toString());
            }
            if(result.equalsIgnoreCase("null\n")){
                list.add("empty");
            }
            else{
                try{
                    JSONArray jArray = new JSONArray(result);
                    for(int i=0;i<jArray.length();i++){
                        JSONObject json_data = jArray.getJSONObject(i);
                        title = json_data.getString("title");
                        list.add(title);
                    }
                }
                catch(JSONException e){
                    Log.e("DATA_PARSING_ERROR", "Error parsing data "+e.toString());
                }
            }
            return list;
        }

     @Override
     protected void onPostExecute(ArrayList<String> list){
         progress.setVisibility(View.GONE);
         ArrayAdapter<String> mArrayAdapter = new ArrayAdapter<String>(context, R.layout.list_display, list);
         //PROBLEM
         mylist.setAdapter(mArrayAdapter);
     }

 }//Retrieve

私は最初に試しsetListAdapter(mArrayAdapter)ましたが、明らかにJavaは更新するリストを知りません。次に、リストをコンストラクターに渡してみました

ListView myList=(ListView)findViewById(android.R.id.list);

そして、私はこのエラーを受け取ります:

android.view.ViewRootImpl$CalledFromWrongThreadException: 
Only the original thread that created a view hierarchy can touch its views.

たぶん、別のクラスからビューを変更しようとしているからでしょうか? この問題を解決するにはどうすればよいですか? 関数は?onPostExecuteを返す必要があります。mArrayAdapterこれはどのように達成できますか?

4

3 に答える 3

1

アダプターを作成して、Search_Resultsアクティビティに設定することをお勧めします。リストのアダプターは、リストが含まれるアクティビティのコンポーネントである必要があります。UIをこのようなAsyncTaskと緊密に結合することは避けたいと考えています。つまり、Retrieveクラスは作業を行って戻るだけで、何が起こるかについての詳細はわかりません。取得するデータ。

Search_Resultsにパブリックメソッドを作成します(たとえば)。これはメソッドupdateAdapterから呼び出すことができます。クラスのメンバー変数onPostExecuteから呼び出すことができます。contextRetrieve

public void updateAdapter(ArrayList<String> list) {
    ArrayAdapter<String> mArrayAdapter = new ArrayAdapter<String>(Search_Results.this, R.layout.list_display, list);
    setListAdapter(mArrayAdapter);
}

そしてでonPostExecute

@Override
protected void onPostExecute(ArrayList<String> list){
    progress.setVisibility(View.GONE);
    context.updateAdapter(list);
}
于 2013-02-19T16:07:00.537 に答える
1

Only the original thread that created a view hierarchy can touch its views.doInBackgroundからUI要素にアクセスしようとしているために取得しています。したがって、doInBackgroundから外部に移動し、onPreExecute内に次のように移動します。

 @Override
    protected void onPreExecute() {
        super.onPreExecute();
         progress.setVisibility(View.VISIBLE); //<< set here
    }
于 2013-02-19T15:53:52.343 に答える
0

コンストラクターListActivityの代わりにオブジェクトを渡すことができListViewます。Retrieve

于 2013-02-19T16:07:25.297 に答える