将 AQuery 与 Android 结合使用
Using AQuery with Android
我需要在我的 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();
}
}
这样做,用户界面就正确更新了,但我认为这不是正确的方法。
那么,我能做什么?
谢谢
安德里亚
如果我没记错的话,您目前正在将异步任务包装在异步任务中。您的 aq.ajax(...)
正在启动一个新线程来进行调用,然后调用您定义的 callback(...)
。
AsyncTask
执行 doInBackground()
,您在此处开始另一个任务。 doInBackground()
方法在您的 ajax 调用完成之前完成。因此 onPostExecute()
在 ajax 调用完成之前执行。
解决方案是省略整个 AsyncTask 结构。只需在您的主 onCreateView
中调用您的 aq.ajax()
并在您定义的回调中调用 returns 时执行您必须执行的操作。 (基本上把你的doInBackGround()
的内容放在你的main
感谢您的回复。根据您的建议,我创建了一个示例项目:基本上,它只有一个文本视图,显示服务器传递的字符串值。这是主要的activity,项目中唯一的:
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 设置了初始化值。
我该如何解决?
再次感谢。
安德里亚
我需要在我的 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();
}
}
这样做,用户界面就正确更新了,但我认为这不是正确的方法。 那么,我能做什么? 谢谢
安德里亚
如果我没记错的话,您目前正在将异步任务包装在异步任务中。您的 aq.ajax(...)
正在启动一个新线程来进行调用,然后调用您定义的 callback(...)
。
AsyncTask
执行 doInBackground()
,您在此处开始另一个任务。 doInBackground()
方法在您的 ajax 调用完成之前完成。因此 onPostExecute()
在 ajax 调用完成之前执行。
解决方案是省略整个 AsyncTask 结构。只需在您的主 onCreateView
中调用您的 aq.ajax()
并在您定义的回调中调用 returns 时执行您必须执行的操作。 (基本上把你的doInBackGround()
的内容放在你的main
感谢您的回复。根据您的建议,我创建了一个示例项目:基本上,它只有一个文本视图,显示服务器传递的字符串值。这是主要的activity,项目中唯一的:
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 设置了初始化值。 我该如何解决? 再次感谢。
安德里亚