1

我在我的一个类中使用新的 Runnable httprequest 数据加载。我使用该类在我的一个活动中填充 ListView,但问题是视图是在加载数据之前加载的。我尝试移动初始化所​​有视图的初始化方法,但什么也没发生。每次加载应用程序时,我都必须重新加载主视图,因为 ListView 中没有条目。LoadReportList() 是创建持有 http 请求方法的类的实例的方法。

 public class HomeActivity extends Activity {

private ArrayList<Report> reportList = null;

ListView listview;

private final boolean DEBUG = true;

private MyCustomArrayAdapter adapter = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);     
}

@Override
protected void onResume()
{
    super.onResume();
    loadReportList();
    initialize();
}

/**
 * This method initializes all the components needed for the activity
 */
private void initialize()
{
    /* Get a reference of the listview in our xml view */
    listview = (ListView) findViewById(R.id.reportsList);

    adapter = new MyCustomArrayAdapter(this, R.layout.single_listview_row);

    try{
        // Populate the list, through the adapter   
        for(final List_Item entry : getListEntries()) {
            adapter.add(entry);
            if(DEBUG)Log.i("HomeActivity","in adding List_Item entries to the adapter");
        }
    }catch(Exception e){
        Log.i("In initialize() HomeActivity","Could not load the list with entries");

        loadReportList();
    }

    listview.setAdapter(adapter);

    listview.setOnItemClickListener(new OnItemClickListener(){  
        public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {

            /* Class to assist us in loading the activity */
            Class editClass = null;
            try {
                editClass = Class.forName(".DetailsActivity");
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            /* create bundle to pass the ID of the deck that was clicked */
            Bundle reportPassed = new Bundle();
            //reportPassed.putInt("Report", reportList.get(4).getId());
            reportPassed.putSerializable("report", reportList.get(position));

            /* Start the new intent and also pass a bundle that will contain the name of the card that was clicked */
            Intent ourIntent = new Intent(HomeActivity.this, editClass);
            ourIntent.putExtras(reportPassed);//passing the bundle to the activity
            //start the activity
            startActivity(ourIntent);
        }
    });
}

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

/* Create the list of objects of type List_Item, in our case it will be Decks */
private List<List_Item> getListEntries(){

    /* Create an ArrayList of List_Items */
    final ArrayList<List_Item> entries = new ArrayList<List_Item>();

    if(reportList == null || reportList.isEmpty())
        loadReportList();

    /* Create the rows for the ListView by adding them into the ArrayList "entries".
     * reportList is a global ArrayList<Report> that we populate by a method call to the class JsonParser.
     * Look above.
     * */
    for(int i = 0; i < reportList.size(); i++) {
        if(DEBUG)Log.i("getListEntries HomeActivity","Passing through reportlistEntries");
        entries.add(
                new List_Item(((Report)reportList.get(i)).getType(), Integer.toString(((Report)reportList.get(i)).getId()), ((Report)reportList.get(i)).getId())
                );
    }
    return entries;
}

//This method loads the reportList arraylist with all Report objects
void loadReportList(){
    try {
        reportList = new JsonParser().getArrayList();
    } catch (UnsupportedEncodingException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IllegalStateException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (JSONException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
}

}

这是我的 HTTP 请求:

//The constructor simply calls the getHttpResponse()
    public JsonParser() throws UnsupportedEncodingException, IllegalStateException,  IOException, JSONException
{
    getHttpResponse();
}
/*
 *  This method returns an HttpResponse
 */
public void getHttpResponse(){
    Log.i("getHttpResponse", "Right after declaring HttpResponse response");      
    new Thread(new Runnable() {
        public void run() {
            runRequest();
        }
      }).start();
}

void runRequest()
{
    HttpResponse response = null;
    HttpClient client = new DefaultHttpClient();
    HttpGet request = new HttpGet();
    try {
        request.setURI(new URI("http://....../report_data.json"));
        response = client.execute(request);
    } catch (URISyntaxException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    if(response!= null)
        Log.i(response.toString(), "testing response.toString()");

    //call to populate the list
    try {
        populateList(response);
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalStateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
4

2 回答 2

2

您可以利用 Android SDK 的 AsyncTask 类,而不是使用 java 线程。您可以在 onPreExecute 方法中显示一个进度对话框,在 doInBackground 方法中执行所有繁重的工作(在您的情况下是 http 的东西),并填充您的列表并在 onPostExecute 方法中关闭进度对话框。您可以创建一个内部类,例如 Task ,它扩展了 AsyncTask 方法并从 onCreate 或 onResume 调用它,只要适合您,就像这样。

new Task().execute();

AsyncTask 被命名为“Painless threading”,因为它可以让我们的生活更轻松。重用已实现的用于此类任务的代码是一种很好的做法。

您可以在 StackOverflow 中找到许多关于 AsyncTasks 使用的线程,例如AsyncTask 中的 progressDialog

于 2013-04-28T20:40:12.423 回答
0

所以你需要做的是在你的 runRequest 代码完成后调用 initialize() 。

我同意上面的海报,即 AsyncTask 将使这变得容易。摆脱 JsonParser 类中的线程代码。AsyncTask 会为你解决这个问题。

这是一个片段。

new AsyncTask<Void, Void, Void>() {
    @Override
    protected Void doInBackground(Void... voids) {
        myparser = new JSONParser();
        myparser.runRequest()
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        initialize();
    }
}.execute();
于 2013-04-28T21:27:42.230 回答