Moved communication with DownloadService into DownloadObserver
This commit is contained in:
parent
7d44c471f2
commit
a2f841c43e
@ -1,18 +1,9 @@
|
||||
package de.danoeh.antennapod.activity;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.view.ActionMode;
|
||||
@ -22,17 +13,18 @@ import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
|
||||
import android.widget.ListView;
|
||||
|
||||
import de.danoeh.antennapod.AppConfig;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.adapter.DownloadlistAdapter;
|
||||
import de.danoeh.antennapod.asynctask.DownloadObserver;
|
||||
import de.danoeh.antennapod.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.service.download.DownloadRequest;
|
||||
import de.danoeh.antennapod.service.download.DownloadService;
|
||||
import de.danoeh.antennapod.service.download.Downloader;
|
||||
import de.danoeh.antennapod.storage.DownloadRequester;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Shows all running downloads in a list. The list objects are DownloadStatus
|
||||
* objects created by a DownloadObserver.
|
||||
@ -49,13 +41,10 @@ public class DownloadActivity extends ActionBarActivity implements
|
||||
private ActionMode mActionMode;
|
||||
private DownloadRequest selectedDownload;
|
||||
|
||||
private DownloadService downloadService = null;
|
||||
boolean mIsBound;
|
||||
|
||||
private AsyncTask<Void, Void, Void> contentRefresher;
|
||||
|
||||
private ListView listview;
|
||||
|
||||
private DownloadObserver downloadObserver;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(UserPreferences.getTheme());
|
||||
@ -68,22 +57,19 @@ public class DownloadActivity extends ActionBarActivity implements
|
||||
Log.d(TAG, "Creating Activity");
|
||||
requester = DownloadRequester.getInstance();
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
downloadObserver = new DownloadObserver(this, new Handler(), observerCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
unbindService(mConnection);
|
||||
unregisterReceiver(contentChanged);
|
||||
downloadObserver.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
registerReceiver(contentChanged, new IntentFilter(
|
||||
DownloadService.ACTION_DOWNLOADS_CONTENT_CHANGED));
|
||||
bindService(new Intent(this, DownloadService.class), mConnection, 0);
|
||||
startContentRefresher();
|
||||
downloadObserver.onResume();
|
||||
if (dla != null) {
|
||||
dla.notifyDataSetChanged();
|
||||
}
|
||||
@ -94,72 +80,8 @@ public class DownloadActivity extends ActionBarActivity implements
|
||||
super.onStop();
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Stopping Activity");
|
||||
stopContentRefresher();
|
||||
}
|
||||
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
downloadService = null;
|
||||
mIsBound = false;
|
||||
Log.i(TAG, "Closed connection with DownloadService.");
|
||||
}
|
||||
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
downloadService = ((DownloadService.LocalBinder) service)
|
||||
.getService();
|
||||
mIsBound = true;
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Connection to service established");
|
||||
dla = new DownloadlistAdapter(DownloadActivity.this, 0,
|
||||
downloadService.getDownloads());
|
||||
listview.setAdapter(dla);
|
||||
dla.notifyDataSetChanged();
|
||||
}
|
||||
};
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private void startContentRefresher() {
|
||||
if (contentRefresher != null) {
|
||||
contentRefresher.cancel(true);
|
||||
}
|
||||
contentRefresher = new AsyncTask<Void, Void, Void>() {
|
||||
private static final int WAITING_INTERVAL = 1000;
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Void... values) {
|
||||
super.onProgressUpdate(values);
|
||||
if (dla != null) {
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Refreshing content automatically");
|
||||
dla.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
while (!isCancelled()) {
|
||||
try {
|
||||
Thread.sleep(WAITING_INTERVAL);
|
||||
publishProgress();
|
||||
} catch (InterruptedException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
|
||||
contentRefresher.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} else {
|
||||
contentRefresher.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private void stopContentRefresher() {
|
||||
if (contentRefresher != null) {
|
||||
contentRefresher.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
@ -247,16 +169,22 @@ public class DownloadActivity extends ActionBarActivity implements
|
||||
dla.setSelectedItemIndex(DownloadlistAdapter.SELECTION_NONE);
|
||||
}
|
||||
|
||||
private BroadcastReceiver contentChanged = new BroadcastReceiver() {
|
||||
|
||||
private DownloadObserver.Callback observerCallback = new DownloadObserver.Callback() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
public void onContentChanged() {
|
||||
if (dla != null) {
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Refreshing content");
|
||||
dla.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadDataAvailable(List<Downloader> downloaderList) {
|
||||
dla = new DownloadlistAdapter(DownloadActivity.this, 0,
|
||||
downloaderList);
|
||||
listview.setAdapter(dla);
|
||||
dla.notifyDataSetChanged();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
150
src/de/danoeh/antennapod/asynctask/DownloadObserver.java
Normal file
150
src/de/danoeh/antennapod/asynctask/DownloadObserver.java
Normal file
@ -0,0 +1,150 @@
|
||||
package de.danoeh.antennapod.asynctask;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.*;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import de.danoeh.antennapod.AppConfig;
|
||||
import de.danoeh.antennapod.service.download.DownloadService;
|
||||
import de.danoeh.antennapod.service.download.Downloader;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Provides access to the DownloadService's list of items that are currently being downloaded.
|
||||
* The DownloadObserver object should be created in the activity's onCreate() method. resume() and pause()
|
||||
* should be called in the activity's onResume() and onPause() methods
|
||||
*/
|
||||
public class DownloadObserver {
|
||||
private static final String TAG = "DownloadObserver";
|
||||
|
||||
/**
|
||||
* Time period between update notifications.
|
||||
*/
|
||||
public static final int WAITING_INTERVAL_MS = 1000;
|
||||
|
||||
private final Activity activity;
|
||||
private final Handler handler;
|
||||
private final Callback callback;
|
||||
|
||||
private DownloadService downloadService = null;
|
||||
private AtomicBoolean mIsBound = new AtomicBoolean(false);
|
||||
|
||||
private Thread refresherThread;
|
||||
private AtomicBoolean refresherThreadRunning = new AtomicBoolean(false);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new download observer.
|
||||
*
|
||||
* @param activity Used for registering receivers
|
||||
* @param handler All callback methods are executed on this handler. The handler MUST run on the GUI thread.
|
||||
* @param callback Callback methods for posting content updates
|
||||
* @throws java.lang.IllegalArgumentException if one of the arguments is null.
|
||||
*/
|
||||
public DownloadObserver(Activity activity, Handler handler, Callback callback) {
|
||||
if (activity == null) throw new IllegalArgumentException("activity = null");
|
||||
if (handler == null) throw new IllegalArgumentException("handler = null");
|
||||
if (callback == null) throw new IllegalArgumentException("callback = null");
|
||||
|
||||
this.activity = activity;
|
||||
this.handler = handler;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
if (AppConfig.DEBUG) Log.d(TAG, "DownloadObserver resumed");
|
||||
activity.registerReceiver(contentChangedReceiver, new IntentFilter(DownloadService.ACTION_DOWNLOADS_CONTENT_CHANGED));
|
||||
activity.bindService(new Intent(activity, DownloadService.class), mConnection, 0);
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
if (AppConfig.DEBUG) Log.d(TAG, "DownloadObserver paused");
|
||||
activity.unregisterReceiver(contentChangedReceiver);
|
||||
activity.unbindService(mConnection);
|
||||
stopRefresher();
|
||||
}
|
||||
|
||||
private BroadcastReceiver contentChangedReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
callback.onContentChanged();
|
||||
startRefresher();
|
||||
}
|
||||
};
|
||||
|
||||
public interface Callback {
|
||||
void onContentChanged();
|
||||
|
||||
void onDownloadDataAvailable(List<Downloader> downloaderList);
|
||||
}
|
||||
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
downloadService = null;
|
||||
mIsBound.set(false);
|
||||
stopRefresher();
|
||||
Log.i(TAG, "Closed connection with DownloadService.");
|
||||
}
|
||||
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
downloadService = ((DownloadService.LocalBinder) service)
|
||||
.getService();
|
||||
mIsBound.set(true);
|
||||
if (AppConfig.DEBUG)
|
||||
Log.d(TAG, "Connection to service established");
|
||||
List<Downloader> downloaderList = downloadService.getDownloads();
|
||||
if (downloaderList != null && !downloaderList.isEmpty()) {
|
||||
callback.onDownloadDataAvailable(downloaderList);
|
||||
startRefresher();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void stopRefresher() {
|
||||
if (refresherThread != null) {
|
||||
refresherThread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
private void startRefresher() {
|
||||
if (refresherThread == null || refresherThread.isInterrupted()) {
|
||||
refresherThread = new Thread(new RefresherThread());
|
||||
refresherThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
private class RefresherThread implements Runnable {
|
||||
|
||||
public void run() {
|
||||
refresherThreadRunning.set(true);
|
||||
while (!Thread.interrupted()) {
|
||||
try {
|
||||
Thread.sleep(WAITING_INTERVAL_MS);
|
||||
} catch (InterruptedException e) {
|
||||
Log.d(TAG, "Refresher thread was interrupted");
|
||||
}
|
||||
if (mIsBound.get()) {
|
||||
postUpdate();
|
||||
}
|
||||
}
|
||||
refresherThreadRunning.set(false);
|
||||
}
|
||||
|
||||
private void postUpdate() {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onContentChanged();
|
||||
List<Downloader> downloaderList = downloadService.getDownloads();
|
||||
if (downloaderList == null || downloaderList.isEmpty()) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user