2014-09-01 2 views
0

먼저 미안하지만 다른 질문에서 아무것도 이해할 수 없거나 내가 내 경우에 구현할 수 없다고 말할 수 있기 때문에 중복을 묻는다면 미안합니다. 사실 나는 에있는 네트워크에서 업데이트 된 것으로 내 ListView을 업데이트하려는 상황에 갇혀 있지만 구현 방법은 몇 가지를 시도했지만 제대로 작동하지는 못합니다. 누구나 할 수있는 방법을 자세히 설명해주십시오, 여기 활동과 비동기 클래스 내 코드입니다AsyncTask에서 listview를 업데이 트하는 방법

package app.balaji.sid.listapp; 

    import android.os.AsyncTask; 
    import android.os.Bundle; 
    import android.support.v7.app.ActionBarActivity; 
    import android.util.Log; 
    import android.view.Menu; 
    import android.view.MenuItem; 
    import android.widget.ArrayAdapter; 
    import android.widget.ListView; 

    import it.sauronsoftware.ftp4j.FTPClient; 
    import it.sauronsoftware.ftp4j.FTPFile; 


    public class ListActivity extends ActionBarActivity { 
     ListView lv; 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_list); 
      lv=(ListView)findViewById(R.id.listView); 
      String[] values = new String[] { "Item 1", 
        "Item 2", 
        "Item 3 ", 
        "Item 4", 
        "Item 5", 
        "Item 6", 
        "Item 7", 
        "Item 8" 
      }; 
      ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
        android.R.layout.simple_list_item_1, android.R.id.text1, values); 
      lv.setAdapter(adapter); 
      new ListFetcher().execute(); 


     } 


     @Override 
     public boolean onCreateOptionsMenu(Menu menu) { 
      // Inflate the menu; this adds items to the action bar if it is present. 
      getMenuInflater().inflate(R.menu.list, 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); 
     } 

     protected class ListFetcher extends AsyncTask<String,String,String>{ 
      String sid; 


      @Override 
      protected String doInBackground(String... params) { 
       String user = "user"; 
       String pass="password"; 
       String host="204.236.238.164"; 

       FTPClient client = new FTPClient(); 

       try { 

        client.connect(host,21); 
        client.login(user, pass); 
        client.setType(FTPClient.TYPE_BINARY); 
        client.changeDirectory("/"); 

        FTPFile[] files = client.list(); 
        String[] fileNames = new String[files.length]; 

        for (int i = 0; i < files.length; i++) 
        { 
         fileNames[i] = files[i].getName(); 
         String logVariable=fileNames[i]; 
         Log.v(sid, logVariable);  // Here i am able to see list in log 
        } 

        }catch (Exception e) 
       { 

        Log.v(sid,e.toString()); 
       } 





       return sid; 
      } 

      protected void onPostExecute() 
      { 

    //i think list should be updated from here but don't know how to do it correctly 
    // i just know i can update my listview by creating a new adapter and assign it to listview but don't know how 
// also i am not able to get the fileNames array here 

      } 



     } 
    } 
+0

A : AsyncTask를 확장 상속 클래스를 만들고이를 MainActivity도 구현하는 인터페이스를 구현하고 게시물에 그것을 호출 할 수 있습니다. B : 파생 상품 내부에서 Activity에 대한 약한 참조를 제공하고 Activity 참조를 파생 상품에 전달하여 Public 메서드를 호출하거나 onPostExecute에서 runOnUiThread를 호출합니다. Thogh는 onPost가 이미 UI 스레드에서 실행된다고 생각했습니다. – icbytes

+0

@icbytes 당신이 할 수있는 몇 가지 예를 들어 내가 안드로이드에 대한 새로운 오전 너무 많이 모르겠다. – Sid

+0

UI 스레드에서 실행되는 @icbytes 그래서'runOnUiThread()'에 대한 필요가 없습니다 – codeMagic

답변

0
당신이 시도한 속는 당신이하지 않는 것을 설명하기 위해 링크를 게시 경우가 대답하는 것이 더 쉽습니다

알다. 어떤 일이 일어나고 있지 않은지 또한 도움이 될 것입니다. 그러나 내가 볼 수 있듯이 새로운 StringonPostExecute()에 전달하고 목록을 업데이트하고 Adapter을 업데이트하면됩니다.

protected void onPostExecute(String result) // get the String you are passing 
{ 

    //i think list should be updated from here but don't know how to do it correctly 
    // I agree. Let's try this 
    if(result != null) // let's make sure you got something 
    { 
     values.add(result); // add the new String to your list 
     adapter.notifyDataSetChanged(); // Hey, Adapter, we've got some new data 

} 

당신은 너무 길이가 동적 일 수 있습니다 ArrayArrayList에 변경해야합니다. 내부 클래스에서 볼 수 있도록 해당 변수와 Adapter 멤버 변수를 만들 수도 있습니다.

public class ListActivity extends ActionBarActivity { 
    ListView lv; 

    // Declare them here 
    ArrayAdapter<String> adapter; 
    ArrayList<String> values = new ArrayList<String>(); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_list); 
    lv=(ListView)findViewById(R.id.listView); 
    values.add("Item 1"); 
    values.add("Items 2"); 

    adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, 
      android.R.id.text1, values); 
    lv.setAdapter(adapter); 
    new ListFetcher().execute(); 
당신이 다음 방금로 업데이트 할 수 있습니다 어댑터에 대한 값의 완전히 새로운 세트를 반환하는 경우에 당신은 배열을

@Override 
     protected String[] doInBackground(Void... params) { 

protected void onPostExecute(String[] result) 

을 반환 할

당신은 당신의 작업에 아무것도 전달되지 않고 새로운 가치. 그냥 몇 가지 값을 추가하는 경우 해당 값을 반복하여 위의 그림과 같이 ArrayList에 추가하고 notifyDataSetChanged()을 호출하면됩니다.

+0

나를 이해하게 해주셔서 감사합니다 그것에 대해 알고 있지만 애플 리케이션 강제 종료입니다 Collections.addAll (values, result); // Log.v (sid, "working here"); adapter.notifyDataSetChanged(); // 여기서 멈 춥니 다. – Sid

+0

당신을 진심으로 환영합니다. 그것은 당신에게 작업 코드를 제공하는 것보다 훨씬 도움이됩니다. 내가 겪고있는 오류를 모른 채 모르겠다. – codeMagic

+0

다음은 앱을 중지 한 후 얻은 로그입니다. 09-02 00 : 05 : 08.221 4074-4074/app.balaji.sid.listapp E/AndroidRuntime : 치명적인 예외 : 주 프로세스 : app.balaji.sid.listapp, PID : 4074 java.lang.NullPointerException at app.balaji.sid.listapp.ListActivity $ ListFetcher.onPostExecute (ListActivity.java:116) at app.balaji.sid.listapp.ListActivity $ ListFetcher.onPostExecute (ListActivity.java : 61) – Sid

0

방금 ​​문제를 해결 했으므로 공유해야한다고 생각하여 동일한 문제에 직면 한 다른 사람들이 쉽게 해결할 수 있습니다.

우선 내 질문에 나는 방금 parametres 문자열로 내 AsyncTask 클래스를 선언했지만 실제로 여기에서 내 ListView를 채워야합니다.

내가 한 그래서 :

protected class ListFetcher extends AsyncTask<ArrayList,ArrayList,ArrayList>{ 
     String sid; 
     ArrayList list; 



     @Override 
     protected ArrayList doInBackground(ArrayList... params) { 
FTPClient client = new FTPClient(); 

      try { 

       client.connect(host,21); 
       client.login(user, pass); 
       client.setType(FTPClient.TYPE_BINARY); 
       client.changeDirectory("/"); 

       FTPFile[] files = client.list(); 
       String[] fileNames = new String[files.length]; 

       for (int i = 0; i < files.length; i++) 
       { 
        fileNames[i] = files[i].getName(); 
String logVariable=fileNames[i]; 
        Log.v(sid, logVariable); 
        values.add(fileNames[i]); 

       } 

       }catch (Exception e) 
      { 

       Log.v(sid,e.toString()); 
      } 





      return list; 
     } 

     protected void onPostExecute(final ArrayList result)//received result but didn't use it because in my case i don't need it instead of it i just updated my arraylist in doInbackground and updated my ui from here 
     { 


      adapter = new ArrayAdapter<String>(ListActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1, values); 
      ListView listView =(ListView)findViewById(R.id.listView); 

      listView.setAdapter(adapter); 




     } 
+0

당신이'Adapter'를 설정하고 있다면'notifyDataSetChanged()'를 호출 할 필요가 없습니다. 그것은 당신이 이미'ListView'에 그것을 설정하고 당신이 목록을 업데이트 할 때를위한 것입니다. – codeMagic

관련 문제