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