2013-08-03 47 views
0

我在我的活動中做了一些後臺處理,並有一個顯示進度的ListView。 I「更新」與我如何維護活動加載之間的ListView狀態android

adapter.notifyDataSetChanged(); 

ListView控件但是當我離開這個活動,然後再回來,後臺進程仍在運行,但列表視圖不更新。這大概是因爲它是一個新對象,而不是前一個。如何在活動加載之間維護我的列表視圖對象?

這是我的活動。我認爲問題在於,下載用於綁定到的「適配器」變量將在活動的onCreate方法中重新創建,並且下載最初綁定的「適配器」變量不再處於活動狀態。

import java.io.File; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.Map; 

import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.net.ConnectivityManager; 
import android.os.Bundle; 
import android.os.Handler; 
import android.preference.PreferenceManager; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.ListView; 
import android.widget.TextView; 
import android.widget.Toast; 


import com.amazonaws.auth.AWSCredentials; 
import com.amazonaws.auth.BasicAWSCredentials; 
import com.amazonaws.services.s3.model.ProgressEvent; 
import com.amazonaws.services.s3.model.ProgressListener; 
import com.amazonaws.services.s3.transfer.TransferManager; 

//import com.amazonaws.auth.AWSCredentials; 
//import com.amazonaws.auth.BasicAWSCredentials; 


public class VideosActivity extends Activity { 

    ListView   video_list;    
    CustomList   adapter; 
    File    storage_dir; 
    SharedPreferences completed_downloads;  //http://developer.android.com/guide/topics/data/data-storage.html 
    SharedPreferences downloaded_data;   //maps position to percent downloaded 
    SharedPreferences queue;     //holds which fiiles are awaiting download 
    String    images[];     //holds references to all thumnails for vids 

    String    volume;     //something like vol1 or vol2 
    String    s3_dir;     //the directory after the boucket that the files are stored in (do not add first slash) 
    String    s3_bucket     = "com--apps"; 
    Handler   handler     = new Handler(); //'tunnel' through whci other threads communicate with main thread 


    Map<String, String[][]> video_config   = new HashMap<String, String[][]>(); //holds info about video thumbs and filenames for all apps 
    ArrayList<String>  arr_videos   = new ArrayList<String>(); //holds video names 
    DownloadQueue   queue_manager  = new DownloadQueue(); 



    @Override 
    public void onCreate(Bundle savedInstanceState) { 

     Log.v("dev", "onCreateCalled"); 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     volume    = getPackageName().split("\\.")[2]; //something like vol1 or vol2 
     s3_dir    = "android/" + volume + "/"; //the directory after the boucket that the files are stored in (do not add first slash) 
     completed_downloads = getSharedPreferences("completed_downloads", 0); 
     downloaded_data  = getSharedPreferences("downloaded_data", 0); 
     queue    = getSharedPreferences("queue", 0); 
     storage_dir   = getApplicationContext().getExternalFilesDir(null);  //private to app, removed with uninstall 
     adapter    = new CustomList(this, R.layout.customlist, arr_videos); 
     video_list   = (ListView)findViewById(R.id.list); 

     video_list.setAdapter(adapter);   //set adapter that specifies list contents 
     ensureStorageDirExists(storage_dir); //make sure storage dir exists 
     set_video_data();      //store vid dat in array 

     ensure_connection_or_warn(); 
    } 

    public boolean ensure_connection_or_warn() 
    { 
     if(have_connection()) 
     { 
      return true; 
     } 
     else 
     { 
      Toast.makeText(this, "No Internet connection", Toast.LENGTH_LONG).show(); 
      return false; 
     } 
    } 
    protected void ensureStorageDirExists(File dir) 
    { 
     if (!dir.exists()) 
     { 
     dir.mkdirs(); 
     } 
    } 

    public void set_video_data() 
    { 


     config_video_data(); //run config 

     images  = video_config.get(getPackageName())[0]; //set images 

     for (String name : video_config.get(getPackageName())[1]) { //set video info, this should be streamlined but is due to legacy code and my crap Java skills, consider doing like this: http://developer.android.com/guide/topics/resources/more-resources.html#TypedArray 
     arr_videos.add(name); 
     } 

    } 


    public SharedPreferences stored_vals() 
    { 

     return PreferenceManager.getDefaultSharedPreferences(this); 
    } 

    public boolean have_connection() 
    { 
     ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 

     if(cm.getActiveNetworkInfo()!=null && cm.getActiveNetworkInfo().isConnected() && cm.getActiveNetworkInfo().isAvailable()) 
     { 
     Log.v("dev", "have internet connection"); 
     return true; 
     } 
     else 
     { 
     Log.v("dev", "No internet connection"); 
     return false; 
     } 

    } 





    public class DownloadQueue 
    { 
     protected void process() 
     { 
     if (queue.size() > 0 && queue.get(0).download_status == "queued") //this is meant to force one download at a time 
     { 
      queue.get(0).start(); 
      adapter.notifyDataSetChanged(); 
     } 
     } 
     protected void add(Integer position) 
     { 
     queue.edit.putInt(position+""); 
     d.download_status = "queued"; 
     adapter.notifyDataSetChanged(); 
     } 
     protected boolean position_is_queued(Integer position) 
     { 
     for (Download d : queue) { 
      if(d.position == position) 
      { 
      return true; 
      } 
     } 

     return false; 
     } 
     protected void remove(Download d) 
     { 
     queue.remove(d); 
     adapter.notifyDataSetChanged(); 
     } 
    } 

    public class CustomList extends ArrayAdapter<String> 
    { 
     View view; 
     int position; 
     Button btn; 

     public CustomList(Context context, int layout_id, ArrayList<String> objects) 
     { 
      super(context, layout_id, objects); 
     } 

     @Override 
     public View getView(final int position, View convertView, ViewGroup view_group) 
     { 
      set_view(convertView); 

      this.position   = position; 
      TextView text_view = (TextView) view.findViewById(R.id.name); 
      ImageView image  = (ImageView) view.findViewById(R.id.img); 
      btn     = (Button) view.findViewById(R.id.play); 

      prepare_btn(); 

      text_view.setText(list_text()); 
      image.setImageResource( 
      getResources().getIdentifier(images[position], "drawable", getPackageName()) 
     ); 

      return view; 
     } 

     public String list_text() 
     { 
      String s = arr_videos.get(position).replace("_", " ").replace(".m4v", ""); 
      s  = s.substring(2, s.length()); 
      return s; 
     } 

     public void set_view(View convertView) 
     { 
      if(convertView == null) 
      { 
      LayoutInflater inflater      = getLayoutInflater(); 
      view           = inflater.inflate(R.layout.customlist, null); 
      } 
      else 
      { 
      view = convertView; 
      } 
     } 

     public Boolean is_downloaded() 
     { 
      return completed_downloads.getBoolean(position + "", false); 
     } 

     public void prepare_btn() 
     { 
      btn.setTag((Integer) position); 

      if(is_downloaded() == true) 
      { 
      btn.setText("Play "); 
      btn.setEnabled(true); 

      btn.setOnClickListener(new OnClickListener() 
      { 
       public void onClick(View btn) 
       { 
       int position = (Integer) btn.getTag(); 
       Intent i   = new Intent(VideosActivity.this, PlayVideoActivity.class); 
       String video_path = storage_dir + "/" + arr_videos.get(position); 

       Log.v("video_path", video_path); 

       i.putExtra("video_path", video_path); 
       startActivity(i); 
       } 
      }); 
      } 
      else if(downloaded_data.contains(position+"")) //it it's currently being downloaded 
      { 
      btn.setText(downloaded_data.getInt(position+"", 0) + "%"); 
      btn.setEnabled(false); 
      } 
      else if(queue_manager.position_is_queued(position)) //it's in the queue 
      { 
      btn.setText("Queued"); 
      btn.setEnabled(false); 
      } 
      else 
      { 
      btn.setText("Download"); 
      btn.setEnabled(true); 

      btn.setOnClickListener(new OnClickListener() 
      { 
       public void onClick(View btn) 
       { 
       int position = (Integer) btn.getTag(); 
       btn.setEnabled(false); 

       queue_manager.add(position); 
       } 
      }); 
      } 
     } 

    } 


    public class Download 
    { 

     File    new_video_file; 
     int    position; 
     String   download_status; 
     com.amazonaws.services.s3.transfer.Download download; 

     protected void queue(int position) 
     { 
      this.position    = position; 
      queue_manager.add(this); 
      queue_manager.process(); 

      //put this download in the queue 
      //start downloading if it's the only one in the queue 
     } 
     protected void start() 
     { 
      if(!ensure_connection_or_warn()) 
      { 
      return; 
      } 

      this.download_status   = "started"; 
      this.new_video_file   = new File(storage_dir, arr_videos.get(position));     //local file to be writtent to 
      TransferManager tx   = new TransferManager(credentials); 
      //http://stackoverflow.com/questions/6976317/android-http-connection-exception 
      this.download    = tx.download(s3_bucket, s3_dir + arr_videos.get(position), new_video_file); 


      download.addProgressListener(new ProgressListener() 
      { 
      public void progressChanged(final ProgressEvent pe) 
      { 
       handler.post(new Runnable() 
       { 
       @Override 
       public void run() 
       { 
        if (pe.getEventCode() == ProgressEvent.COMPLETED_EVENT_CODE) 
        { 
        Download.this.onComplete(); 
        } 
        else 
        { 
        Download.this.onProgressUpdate(); 
        } 
       } 
       }); 
      } 
      }); 
     } 

     //protected void onProgressUpdate(Double progress) 
     protected void onProgressUpdate() 
     { 
      this.download_status   = "downloading"; 
      Double progress = this.download.getProgress().getPercentTransfered(); 
      Integer percent = progress.intValue(); 
      //Log.v("runnable", percent + ""); 

      downloaded_data.edit().putInt(position+"", percent).commit(); 


      adapter.notifyDataSetChanged(); 
     } 
     protected void onComplete() 
     { 
      Log.v("dev", "download complete!!!"); 
      //downloaded_data.remove(position); 

      this.download_status   = "complete"; 

      completed_downloads.edit().putBoolean(position + "", true).commit(); 

      queue_manager.remove(this); 
      queue_manager.process(); 

      adapter.notifyDataSetChanged(); 


     // this.download.abort(); 
     } 
    } 


} 

回答

0

不完全相信後臺處理過程中發生了什麼和你是什麼的ListView狀態的意思,但我的建議是:

嘗試以下操作:

@Override 
protected void onResume() { 
    super.onResume(); 

    yourAdapter.clear(); 
    yourAdapter.addAll(yourData); // API level [1..10] use for(..){ yourAdapter.add(yourData.get(index)) } 
    yourAdapter.notifyDataSetChanged(); 
} 

原因:

適配器保留所有元素的副本,因此當您調用notifyDataSetChanged時,它會檢查自己的元素副本

+0

這不會解決我的問題,因爲上一個BG進程綁定到其進程回調中的不同適配器對象...我更新了上面的代碼,但我擔心它太密集而無法使用。 – pixelearth