0

正确填充我已经从web服务填充的ArrayList的应用程序。 Web服务从AsyncTask调用。当我在onPostExecute中测试它时,ArrayList被填充。 ArrayList被定义为一个实例变量。为什么当AsyncTask完成时是arrayList填充的,但是当我测试实例变量本身后,它是空的。 Async似乎没有正确设置值。ArrayList的不的AsyncTask

一旦异步完成我传递ArrayList的一个arrayAdapter,但我的ListView是空的。

测试:在onPostExecute

Log.e(TAG, "array from WS = " + array.size()); // returns 4 

测试:在onCreate

Log.e(TAG, "checking to see if array is null " + array.size()); // returns 0 



package com.carefreegroup; 

public class GetRotaDetails extends NfcBaseActivity implements OnItemClickListener 
{ 
ArrayList<ArrayList<String>> array; 
MySimpleArrayAdapter arrayAdapter; 
Intent intent; 
private static final String TAG = GetRotaDetails.class.getSimpleName(); 
ListView listView; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    array = new ArrayList<ArrayList<String>>(); 
    nfcscannerapplication = (NfcScannerApplication) getApplication(); 
    intent = this.getIntent(); 
    setContentView(R.layout.getrotadetailslayout); 
    listView = (ListView) findViewById(R.id.getrotadetailslistview); 

    //set titlebar to carer's name 
    Cursor cursorCarerName = nfcscannerapplication.loginValidate.queryAllFromCarer(); 
    cursorCarerName.moveToLast(); 
    String carerTitleName = cursorCarerName.getString(cursorCarerName 
      .getColumnIndex(LoginValidate.C_CARER_NAME)); 
    setTitle(carerTitleName + " is currently logged in"); 

    callID = intent.getStringExtra("callIDExtra"); 
    Log.e(TAG, "callID = " + callID); 
    String[] params = { callID }; 
    AsyncGetRotaDetails agrd = new AsyncGetRotaDetails(); 
    agrd.execute(params); 

    Log.e(TAG, "checking to see if array is null " + array.size()); 
    if (arrayAdapter == null){ 
     MySimpleArrayAdapter arrayAdapter = new MySimpleArrayAdapter(this, array); 
     listView.setAdapter(arrayAdapter); 
    } 
    listView.setAdapter(arrayAdapter); 
    listView.setOnItemClickListener(this); 


}// end of onCreate 

@Override 
protected void onResume() { 


    super.onResume(); 
} 


private class AsyncGetRotaDetails extends AsyncTask<String, Void, String> { 

    ProgressDialog progressDialog; 
    String rotaDetails = null; 

    @Override 
    protected void onPreExecute() { 
     progressDialog = ProgressDialog 
       .show(GetRotaDetails.this, "Connecting to Server", 
         " retrieving rota details...", true); 

    }; 

    @Override 
    protected String doInBackground(String... params) { 

     try { 
      Log.e(TAG, "inside doInBackground"); 

      rotaDetails = nfcscannerapplication.loginWebservice.getRotaDetail(params[0]); 

     } catch (Exception e) { 

      e.printStackTrace(); 

     } 
     return rotaDetails; 

    } 

    @Override 
    protected void onPostExecute(String xmlResult) { 
     super.onPostExecute(xmlResult); 
     if (progressDialog != null) 
      progressDialog.dismiss(); 

     if (rotaDetails != null) { 



      RetrieveExtraDetails red = new RetrieveExtraDetails(); 
      array = red.getExtraDetails(xmlResult); 
      Log.e(TAG, "array from WS = " + array.size()); 

     } else { 

      AlertDialog alertDialog = new AlertDialog.Builder(
        GetRotaDetails.this).create(); 
      alertDialog.setTitle("Signal/Server Test"); 
      alertDialog.setMessage("No Phone Signal or Server Problem"); 

      alertDialog.setButton("OK", 
        new DialogInterface.OnClickListener() { 
         public void onClick(DialogInterface dialog, 
           int which) { 

          onStart(); 
         } 
        }); 

      alertDialog.show(); 

     } 

    }// end of postExecute 

}//end of Async 

private class MySimpleArrayAdapter extends ArrayAdapter<String> { 



    private final Context context; 
    private final ArrayList<?> list; 

    public MySimpleArrayAdapter(Context context, ArrayList<?> list) { 

     super(context, R.layout.getrotadetailsrow); 
     Log.e(TAG, "inside adapter constructor"); 
     this.context = context; 
     this.list = list; 


    }// end of constructor 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     LayoutInflater inflater = (LayoutInflater) context 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

     View rowView = inflater.inflate(R.layout.getrotadetailsrow, parent, 
       false); 

     TextView recTypeID = (TextView) rowView 
       .findViewById(R.id.rectypeid); 

     TextView recType = (TextView) rowView 
       .findViewById(R.id.rectype); 

     TextView name = (TextView) rowView 
       .findViewById(R.id.name); 

     TextView relationship = (TextView) rowView 
       .findViewById(R.id.relationship); 

     TextView address = (TextView) rowView 
       .findViewById(R.id.address); 

     TextView postCode = (TextView) rowView 
       .findViewById(R.id.postcode); 

     TextView telNo = (TextView) rowView 
       .findViewById(R.id.telno); 

     TextView keySafe = (TextView) rowView 
       .findViewById(R.id.keysafe); 

     TextView notes = (TextView) rowView 
       .findViewById(R.id.notes); 

     TextView meds = (TextView) rowView 
       .findViewById(R.id.meds); 

     String record = list.get(position).toString(); 

     Log.e(TAG, "record = " + record); 
     recTypeID.setText(record); 
     return super.getView(position, convertView, parent); 
    } 

} 

@Override 
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
    // TODO Auto-generated method stub 

} 

} 

回答

0

让你的ListView的一个字段类和

使用

listView.setAdapter(arrayAdapter); 
listView.setOnItemClickListener(this); 

onPostExecute(字符串结果)方法

,但我的建议是:

使用加载微调器直到数据被提取并且适配器被设置,否则行为是Activity显示为空和3-5秒后突然出现整个列表,这是一种糟糕的用户体验。

通常我们使用异步任务没有任何负载时微调获取的数据是用户界面,而不是一个ListView这是UI的主要组成部分的一小部分。

和不检查阵列中的onCreate长度()。它将永远是0。因为代码流将是:

1.创建阵列

2.检查其长度在的onCreate // 0作为没有什么是被添加

3 。到Array添加数据在背景

4.检查其长度在onPostExecute(字符串结果)//实际长度

+0

嗨,我的举动大部分的东西类范围和设定从postExecute适配器和ListView。异步仍然没有完成,然后在执行agrd之后继续执行。执行(PARAMS); – turtleboy

+0

postEx中的长度始终为4.但我的列表不显示/填充 – turtleboy

+0

在此处发布您的更新代码。 –

1

实际上,的AsyncTask异步运行它不是一个阻塞调用(如execute()方法返回,onPostExecute的执行之后())。所以你需要在下载数据时通知onPostExecute()中的适配器。它是一种多线程相关的问题,当执行()行执行的线程被用于的AsyncTask和的onCreate()的执行移动到下一行,所以同时,doInBackground()和的onCreate()创建将在的AsyncTask螺纹和UI来执行线程分别。

+0

是的,这听起来是正确的。我怎样才能做到这一通知? – turtleboy

+1

移动一个ArrayAdapter变量类的成员变量,然后调用arrayAdapter.notifyDataSetChanged()从onPostExecute() –

+0

没有它仍为0 – turtleboy