0

サーバーへの非同期呼び出しを行うために、Android プロジェクトで AQuery を使用する必要があります。サーバーを呼び出したいだけで、データが得られたら、これらのデータでビューを更新します。そこで、AsyncTask 内に非同期呼び出しを記述しました。以下に、私がしたことを示します。

public class Tab1Fragment extends Fragment implements OnItemClickListener {

    private ListView categorieListView ; 

    private ArrayAdapter<String> listAdapterCategorie ;
    private AQuery aq;
    private String[] lista = null;
    private ProgressDialog pDialog;
    private String nome_categoria;
    private int[] arrayID = null;

    ArrayList<String> planetList;
    JsonRequestActivity categoryAjax;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        pDialog = new ProgressDialog(getActivity());
        LinearLayout view = (LinearLayout) inflater.inflate(R.layout.tab1, container, false);
        aq = new AQuery(this.getActivity(), view);                       
        categorieListView = (ListView) view.findViewById(R.id.listView1);        
        //new FetchMyDataTask(this.getActivity(), new FetchMyDataTaskCompleteListener(listAdapterCategorie, categorieListView, this.getActivity()), aq).execute("InputString");

        if(lista == null){
            new AggiornaLista().execute();
        }else{
            listAdapterCategorie = new ArrayAdapter<String>(getActivity().getApplicationContext(), R.layout.categoriegenerali, R.id.nomeAttivita, lista);
            categorieListView.setAdapter( listAdapterCategorie );
        }

        categorieListView.setOnItemClickListener(this);
        return view;
    }


    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {

        Intent esercizioScelto = new Intent(this.getActivity(), CategoriaScelta.class);
        nome_categoria = categorieListView.getItemAtPosition(position).toString();
        esercizioScelto.putExtra("nome_categoria", nome_categoria);
        esercizioScelto.putExtra("id_categoria", arrayID[position]);
        startActivity(esercizioScelto);   
    }             

    private class AggiornaLista extends AsyncTask<String, Void, String[]>{
        @Override
        protected void onPreExecute(){
            super.onPreExecute();
            pDialog.setMessage("Caricamento dati server");                  
        }

        @Override
        protected String[] doInBackground(String... params) {
            String url = Const.URL_JSON_ARRAY;

            Map<String, String> params2 = new HashMap<String, String>();
            params2.put("type", "get_all");

            aq.ajax(url, params2, JSONArray.class, new AjaxCallback<JSONArray>() {                                                

                @Override
                public void callback(String url, JSONArray json, AjaxStatus status) {
                    if(json != null){
                        lista = new String[json.length()];
                        arrayID = new int[json.length()];
                        for(int i = 0; i < json.length(); i++){
                            try {
                                lista[i] = result.getJSONObject(i).getString("Name");
                                arrayID[i] = result.getJSONObject(i).getInt("ID");
                            } 
                            catch (JSONException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                        //Toast.makeText(aq.getContext(), jsonArray.toString(), Toast.LENGTH_LONG).show();
                    }else{                              
                        //ajax error, show error code
                        //Toast.makeText(aq.getContext(), "Error:" + status.getCode(), Toast.LENGTH_LONG).show();
                    }
                    // do something with the result                             

                }
            });       
            return lista;
        }

        @Override
        protected void onPostExecute(String result[])
        {
            super.onPostExecute(result);
            pDialog.dismiss();
            listAdapterCategorie = new ArrayAdapter<String>(getActivity().getApplicationContext(), R.layout.categoriegenerali, R.id.nomeAttivita, result);

            // Set the ArrayAdapter as the ListView's adapter. 
            categorieListView.setAdapter( listAdapterCategorie );

        }

    }

}

その実装は、私が期待したようには機能しません。実際、onPostExecute 内では、doInBackground によって返されるパラメーターは更新されず、初期化値 (null) が含まれています。次に、AsyncTask でのみ何かを変更しました。

private class AggiornaLista extends AsyncTask<String, Void, Void>
    {
        @Override
        protected void onPreExecute()
        {
            super.onPreExecute();
            pDialog.setMessage("Caricamento dati server");

        }

        @Override
        protected Void doInBackground(String... params) {
            String url = Const.URL_JSON_ARRAY;

            Map<String, String> params2 = new HashMap<String, String>();
            params2.put("type", "get_all");

            aq.ajax(url, params2, JSONArray.class, new AjaxCallback<JSONArray>() {                                                
                @Override
                public void callback(String url, JSONArray json, AjaxStatus status) {
                    if(json != null){
                        lista = new String[json.length()];
                        arrayID = new int[json.length()];
                        for(int i = 0; i < json.length(); i++){
                            try {
                                lista[i] = result.getJSONObject(i).getString("Name");
                                arrayID[i] = result.getJSONObject(i).getInt("ID");
                            } catch (JSONException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                        //Toast.makeText(aq.getContext(), jsonArray.toString(), Toast.LENGTH_LONG).show();
                    }else{                              
                        //ajax error, show error code
                        //Toast.makeText(aq.getContext(), "Error:" + status.getCode(), Toast.LENGTH_LONG).show();
                    }
                    // do something with the result                             
                    listAdapterCategorie = new ArrayAdapter<String>(getActivity().getApplicationContext(), R.layout.categoriegenerali, R.id.nomeAttivita, lista);

                    // Set the ArrayAdapter as the ListView's adapter. 
                    categorieListView.setAdapter( listAdapterCategorie );
                }
            });       
            return null;
        }

        @Override
        protected void onPostExecute(Void result)
        {
            super.onPostExecute(result);
            pDialog.dismiss();
        }

    }

そうすることで、ユーザーインターフェイスは正しく更新されますが、それは正しい方法ではないと思います。それで、なにかお手伝いできますか?ありがとう。

アンドレア

4

2 に答える 2

1

私が間違っていなければ、現在非同期タスクを非同期タスクにラップしています。あなたaq.ajax(...)は新しいスレッドを開始して呼び出しを行い、callback(...)定義したを呼び出します。はAsyncTaskを実行しdoInBackground()、そこで別のタスクを開始します。doInBackground()ajax 呼び出しが完了する前に、メソッドが終了します。したがって、onPostExecute()ajax 呼び出しが終了する前に が実行されます。

解決策は、AsyncTask 構造全体を省略することです。aq.ajax()メインで呼び出してonCreateView、定義したコールバックで呼び出しが返されたときに、必要なことを実行するだけです。(基本的にあなたの内容をdoInBackGround()あなたのメインに入れます

于 2015-05-28T09:05:28.773 に答える
0

お返事ありがとうございます。あなたの提案に従って、サンプル プロジェクトを作成しました。基本的には、サーバーから渡された文字列値を表示するテキスト ビューしかありません。これは主な活動であり、プロジェクトで唯一のものです。

public class MainActivity extends Activity {
    private AQuery aq;
    private String serverParameter = "";
    private TextView myTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myTextView = (TextView)findViewById(R.id.myTextView);
        aq = new AQuery(this);
        asyncCall();
        myTextView.setText(serverParameter);        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void asyncCall(){

        String url = "http://tryourweb.altervista.org/LocalOfferte0.0/src/category_controller.php";

        Map<String, String> params = new HashMap<String, String>();
        params.put("type", "get_all");

        aq.ajax(url, params, JSONArray.class, new AjaxCallback<JSONArray>() {
            @Override
            public void callback(String url, JSONArray json, AjaxStatus status) {
                if(json != null){
                    //successful ajax call, show status code and json content
                    try {
                        Toast.makeText(aq.getContext(), status.getCode() + ":" + json.getJSONObject(0).getString("Name"), Toast.LENGTH_LONG).show();
                        serverParameter = json.getJSONObject(0).getString("Name");
                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }else{  
                    //ajax error, show error code
                    Toast.makeText(aq.getContext(), "Error:" + status.getCode(), Toast.LENGTH_LONG).show();
                }
            }
        });     

    }
}

残念ながら、setText は初期化値を設定します。どうすれば解決できますか?ありがとうございました。

アンドレア

于 2015-05-29T08:54:04.013 に答える