Implemented Entry/Loader/Adapter for NetDbListFragment
This commit is contained in:
24
res/layout/listitem_leaseset.xml
Normal file
24
res/layout/listitem_leaseset.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp" >
|
||||
|
||||
<!-- The nickname of the LeaseSet -->
|
||||
<TextView android:id="@+id/ls_nickname"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="3dp"
|
||||
android:textSize="16sp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginRight="5dp"
|
||||
android:text="LeaseSet nickname" />
|
||||
|
||||
<!-- The hash of the LeaseSet -->
|
||||
<TextView android:id="@+id/ls_hash"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/ls_nickname"
|
||||
android:text="LeaseSet hash" />
|
||||
|
||||
</RelativeLayout>
|
25
res/layout/listitem_routerinfo.xml
Normal file
25
res/layout/listitem_routerinfo.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp" >
|
||||
|
||||
<!-- The hash of the RouterInfo -->
|
||||
<TextView android:id="@+id/ri_hash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="3dp"
|
||||
android:textSize="16sp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginRight="5dp"
|
||||
android:text="RouterInfo hash" />
|
||||
|
||||
<!-- Country flag -->
|
||||
<ImageView android:id="@+id/ri_country"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="Country" />
|
||||
|
||||
</RelativeLayout>
|
@ -45,8 +45,13 @@
|
||||
<string name="action_reload">Reload</string>
|
||||
<string name="hint_search_addressbook">Search addressbook</string>
|
||||
|
||||
<string name="router_not_running">The router is not running.</string>
|
||||
|
||||
<string name="graphs_not_ready">Graphs are not ready, or the router is not running. Try again later.</string>
|
||||
|
||||
<string name="netdb_routers_empty">No routers in your NetDB.</string>
|
||||
<string name="netdb_leases_empty">No LeaseSets in your NetDB.</string>
|
||||
|
||||
<string name="menu_settings">Settings</string>
|
||||
<string name="settings_enable">Enable</string>
|
||||
<string name="settings_desc_subscriptions">Subscription URLs</string>
|
||||
|
@ -3,13 +3,16 @@ package net.i2p.android.router.activity;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.fragment.NetDbListFragment;
|
||||
import net.i2p.android.router.fragment.NetDbSummaryPagerFragment;
|
||||
import net.i2p.android.router.loader.NetDbEntry;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBar.Tab;
|
||||
|
||||
public class NetDbActivity extends I2PActivityBase {
|
||||
public class NetDbActivity extends I2PActivityBase implements
|
||||
NetDbListFragment.RouterContextProvider,
|
||||
NetDbListFragment.OnEntrySelectedListener {
|
||||
/**
|
||||
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
|
||||
* device.
|
||||
@ -72,8 +75,8 @@ public class NetDbActivity extends I2PActivityBase {
|
||||
|
||||
// In two-pane mode, list items should be given the
|
||||
// 'activated' state when touched.
|
||||
//rf.setActivateOnItemClick(true);
|
||||
//lf.setActivateOnItemClick(true);
|
||||
rf.setActivateOnItemClick(true);
|
||||
lf.setActivateOnItemClick(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,4 +105,9 @@ public class NetDbActivity extends I2PActivityBase {
|
||||
super.onTabSelected(tab, ft);
|
||||
}
|
||||
}
|
||||
|
||||
// NetDbListFragment.OnEntrySelectedListener
|
||||
|
||||
public void onEntrySelected(NetDbEntry entry) {
|
||||
}
|
||||
}
|
||||
|
61
src/net/i2p/android/router/adapter/NetDbEntryAdapter.java
Normal file
61
src/net/i2p/android/router/adapter/NetDbEntryAdapter.java
Normal file
@ -0,0 +1,61 @@
|
||||
package net.i2p.android.router.adapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.loader.NetDbEntry;
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class NetDbEntryAdapter extends ArrayAdapter<NetDbEntry> {
|
||||
private final LayoutInflater mInflater;
|
||||
|
||||
public NetDbEntryAdapter(Context context) {
|
||||
super(context, android.R.layout.simple_list_item_2);
|
||||
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
}
|
||||
|
||||
public void setData(List<NetDbEntry> entries) {
|
||||
clear();
|
||||
if (entries != null) {
|
||||
for (NetDbEntry entry : entries) {
|
||||
add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View v;
|
||||
NetDbEntry entry = getItem(position);
|
||||
|
||||
if (entry.isRouterInfo()) {
|
||||
v = mInflater.inflate(R.layout.listitem_routerinfo, parent, false);
|
||||
|
||||
TextView hash = (TextView) v.findViewById(R.id.ri_hash);
|
||||
hash.setText(entry.getHash());
|
||||
|
||||
int countryIcon = entry.getCountryIcon();
|
||||
if (countryIcon > 0) {
|
||||
ImageView country = (ImageView) v.findViewById(R.id.ri_country);
|
||||
country.setImageDrawable(getContext().getResources()
|
||||
.getDrawable(countryIcon));
|
||||
}
|
||||
} else {
|
||||
v = mInflater.inflate(R.layout.listitem_leaseset, parent, false);
|
||||
|
||||
TextView hash = (TextView) v.findViewById(R.id.ls_hash);
|
||||
hash.setText(entry.getHash());
|
||||
|
||||
TextView nickname = (TextView) v.findViewById(R.id.ls_nickname);
|
||||
nickname.setText(entry.getNickname());
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
@ -1,8 +1,180 @@
|
||||
package net.i2p.android.router.fragment;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
import java.util.List;
|
||||
|
||||
public class NetDbListFragment extends Fragment {
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.adapter.NetDbEntryAdapter;
|
||||
import net.i2p.android.router.loader.NetDbEntry;
|
||||
import net.i2p.android.router.loader.NetDbEntryLoader;
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
|
||||
public class NetDbListFragment extends ListFragment
|
||||
implements LoaderManager.LoaderCallbacks<List<NetDbEntry>> {
|
||||
public static final String SHOW_ROUTERS = "show_routers";
|
||||
|
||||
private static final int ROUTER_LOADER_ID = 1;
|
||||
private static final int LEASESET_LOADER_ID = 2;
|
||||
/**
|
||||
* The serialization (saved instance state) Bundle key representing the
|
||||
* activated item position. Only used on tablets.
|
||||
*/
|
||||
private static final String STATE_ACTIVATED_POSITION = "activated_position";
|
||||
|
||||
RouterContextProvider mRouterContextProvider;
|
||||
OnEntrySelectedListener mEntrySelectedCallback;
|
||||
private NetDbEntryAdapter mAdapter;
|
||||
private boolean mRouters;
|
||||
/**
|
||||
* The current activated item position. Only used on tablets.
|
||||
*/
|
||||
private int mActivatedPosition = ListView.INVALID_POSITION;
|
||||
private boolean mActivateOnItemClick = false;
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface RouterContextProvider {
|
||||
public RouterContext getRouterContext();
|
||||
}
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface OnEntrySelectedListener {
|
||||
public void onEntrySelected(NetDbEntry entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
|
||||
// This makes sure that the container activity has implemented
|
||||
// the callback interface. If not, it throws an exception
|
||||
try {
|
||||
mRouterContextProvider = (RouterContextProvider) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString()
|
||||
+ " must implement RouterContextProvider");
|
||||
}
|
||||
|
||||
// This makes sure that the container activity has implemented
|
||||
// the callback interface. If not, it throws an exception
|
||||
try {
|
||||
mEntrySelectedCallback = (OnEntrySelectedListener) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString()
|
||||
+ " must implement OnEntrySelectedListener");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
// Restore the previously serialized activated item position.
|
||||
if (savedInstanceState != null
|
||||
&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
|
||||
setActivatedPosition(savedInstanceState
|
||||
.getInt(STATE_ACTIVATED_POSITION));
|
||||
}
|
||||
|
||||
// When setting CHOICE_MODE_SINGLE, ListView will automatically
|
||||
// give items the 'activated' state when touched.
|
||||
getListView().setChoiceMode(
|
||||
mActivateOnItemClick ? ListView.CHOICE_MODE_SINGLE
|
||||
: ListView.CHOICE_MODE_NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mAdapter = new NetDbEntryAdapter(getActivity());
|
||||
mRouters = getArguments().getBoolean(SHOW_ROUTERS);
|
||||
|
||||
setListAdapter(mAdapter);
|
||||
|
||||
if (getRouterContext() == null) {
|
||||
setEmptyText(getResources().getString(
|
||||
R.string.router_not_running));
|
||||
} else {
|
||||
setEmptyText(getResources().getString((mRouters ?
|
||||
R.string.netdb_routers_empty :
|
||||
R.string.netdb_leases_empty)));
|
||||
|
||||
setListShown(false);
|
||||
getLoaderManager().initLoader(mRouters ? ROUTER_LOADER_ID
|
||||
: LEASESET_LOADER_ID, null, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView parent, View view, int pos, long id) {
|
||||
super.onListItemClick(parent, view, pos, id);
|
||||
mEntrySelectedCallback.onEntrySelected(mAdapter.getItem(pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if (mActivatedPosition != ListView.INVALID_POSITION) {
|
||||
// Serialize and persist the activated item position.
|
||||
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on activate-on-click mode. When this mode is on, list items will be
|
||||
* given the 'activated' state when touched.
|
||||
*/
|
||||
public void setActivateOnItemClick(boolean activateOnItemClick) {
|
||||
mActivateOnItemClick = activateOnItemClick;
|
||||
}
|
||||
|
||||
private void setActivatedPosition(int position) {
|
||||
if (position == ListView.INVALID_POSITION) {
|
||||
getListView().setItemChecked(mActivatedPosition, false);
|
||||
} else {
|
||||
getListView().setItemChecked(position, true);
|
||||
}
|
||||
|
||||
mActivatedPosition = position;
|
||||
}
|
||||
|
||||
// Duplicated from I2PFragmentBase because this extends ListFragment
|
||||
private RouterContext getRouterContext() {
|
||||
return mRouterContextProvider.getRouterContext();
|
||||
}
|
||||
|
||||
// LoaderManager.LoaderCallbacks<List<NetDbEntry>>
|
||||
|
||||
public Loader<List<NetDbEntry>> onCreateLoader(int id, Bundle args) {
|
||||
return new NetDbEntryLoader(getActivity(),
|
||||
getRouterContext(), mRouters);
|
||||
}
|
||||
|
||||
public void onLoadFinished(Loader<List<NetDbEntry>> loader,
|
||||
List<NetDbEntry> data) {
|
||||
if (loader.getId() == (mRouters ?
|
||||
ROUTER_LOADER_ID : LEASESET_LOADER_ID)) {
|
||||
mAdapter.setData(data);
|
||||
|
||||
if (isResumed()) {
|
||||
setListShown(true);
|
||||
} else {
|
||||
setListShownNoAnimation(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onLoaderReset(Loader<List<NetDbEntry>> loader) {
|
||||
if (loader.getId() == (mRouters ?
|
||||
ROUTER_LOADER_ID : LEASESET_LOADER_ID)) {
|
||||
mAdapter.setData(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
73
src/net/i2p/android/router/loader/NetDbEntry.java
Normal file
73
src/net/i2p/android/router/loader/NetDbEntry.java
Normal file
@ -0,0 +1,73 @@
|
||||
package net.i2p.android.router.loader;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.data.LeaseSet;
|
||||
import net.i2p.data.RouterInfo;
|
||||
|
||||
public class NetDbEntry {
|
||||
private final boolean mIsRI;
|
||||
|
||||
private final RouterInfo mRI;
|
||||
private final String mCountry;
|
||||
|
||||
private final LeaseSet mLS;
|
||||
private final String mNick;
|
||||
|
||||
public static NetDbEntry fromRouterInfo(RouterInfo ri, String country) {
|
||||
return new NetDbEntry(true, ri, country, null, "");
|
||||
}
|
||||
|
||||
public static NetDbEntry fromLeaseSet(LeaseSet ls, String nick) {
|
||||
return new NetDbEntry(false, null, "", ls, nick);
|
||||
}
|
||||
|
||||
public NetDbEntry(boolean isRI,
|
||||
RouterInfo ri, String country,
|
||||
LeaseSet ls, String nick) {
|
||||
mIsRI = isRI;
|
||||
|
||||
mRI = ri;
|
||||
mCountry = country;
|
||||
|
||||
mLS = ls;
|
||||
mNick = nick;
|
||||
}
|
||||
|
||||
public boolean isRouterInfo() {
|
||||
return mIsRI;
|
||||
}
|
||||
|
||||
public RouterInfo getRouterInfo() {
|
||||
return mRI;
|
||||
}
|
||||
|
||||
public LeaseSet getLeaseSet() {
|
||||
return mLS;
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
if (mIsRI) {
|
||||
return mRI.getIdentity().getHash().toBase64();
|
||||
} else {
|
||||
return mLS.getDestination().calculateHash().toBase64();
|
||||
}
|
||||
}
|
||||
|
||||
public int getCountryIcon() {
|
||||
// http://daniel-codes.blogspot.com/2009/12/dynamically-retrieving-resources-in.html
|
||||
try {
|
||||
Class res = R.drawable.class;
|
||||
Field field = res.getField("flag_" + mCountry);
|
||||
return field.getInt(null);
|
||||
}
|
||||
catch (Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return mNick;
|
||||
}
|
||||
}
|
191
src/net/i2p/android/router/loader/NetDbEntryLoader.java
Normal file
191
src/net/i2p/android/router/loader/NetDbEntryLoader.java
Normal file
@ -0,0 +1,191 @@
|
||||
package net.i2p.android.router.loader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.LeaseSet;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.TunnelPoolSettings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
|
||||
public class NetDbEntryLoader extends AsyncTaskLoader<List<NetDbEntry>> {
|
||||
private RouterContext mRContext;
|
||||
private boolean mRouters;
|
||||
private List<NetDbEntry> mData;
|
||||
private Handler mHandler;
|
||||
private NetDbMonitor mMonitor;
|
||||
|
||||
public NetDbEntryLoader(Context context, RouterContext rContext, boolean routers) {
|
||||
super(context);
|
||||
mRContext = rContext;
|
||||
mRouters = routers;
|
||||
mHandler = new Handler();
|
||||
}
|
||||
|
||||
private static class RouterInfoComparator implements Comparator<RouterInfo> {
|
||||
public int compare(RouterInfo l, RouterInfo r) {
|
||||
return l.getIdentity().getHash().toBase64().compareTo(r.getIdentity().getHash().toBase64());
|
||||
}
|
||||
}
|
||||
|
||||
private class LeaseSetComparator implements Comparator<LeaseSet> {
|
||||
public int compare(LeaseSet l, LeaseSet r) {
|
||||
Destination dl = l.getDestination();
|
||||
Destination dr = r.getDestination();
|
||||
boolean locall = mRContext.clientManager().isLocal(dl);
|
||||
boolean localr = mRContext.clientManager().isLocal(dr);
|
||||
if (locall && !localr) return -1;
|
||||
if (localr && !locall) return 1;
|
||||
return dl.calculateHash().toBase64().compareTo(dr.calculateHash().toBase64());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetDbEntry> loadInBackground() {
|
||||
List<NetDbEntry> ret = new ArrayList<NetDbEntry>();
|
||||
if (mRContext.netDb().isInitialized()) {
|
||||
if (mRouters) {
|
||||
Set<RouterInfo> routers = new TreeSet<RouterInfo>(new RouterInfoComparator());
|
||||
routers.addAll(mRContext.netDb().getRouters());
|
||||
for (RouterInfo ri : routers) {
|
||||
String country = mRContext.commSystem().getCountry(ri.getIdentity().getHash());
|
||||
NetDbEntry entry = NetDbEntry.fromRouterInfo(ri, country);
|
||||
ret.add(entry);
|
||||
}
|
||||
} else {
|
||||
Set<LeaseSet> leases = new TreeSet<LeaseSet>(new LeaseSetComparator());
|
||||
leases.addAll(mRContext.netDb().getLeases());
|
||||
for (LeaseSet ls : leases) {
|
||||
String nick;
|
||||
Destination dest = ls.getDestination();
|
||||
if (mRContext.clientManager().isLocal(dest)) {
|
||||
TunnelPoolSettings in = mRContext.tunnelManager().getInboundSettings(
|
||||
dest.calculateHash());
|
||||
if (in != null && in.getDestinationNickname() != null)
|
||||
nick = in.getDestinationNickname();
|
||||
else
|
||||
nick = dest.toBase64().substring(0, 6);
|
||||
} else {
|
||||
String host = mRContext.namingService().reverseLookup(dest);
|
||||
if (host != null)
|
||||
nick = host;
|
||||
else
|
||||
nick = dest.toBase64().substring(0, 6);
|
||||
}
|
||||
NetDbEntry entry = NetDbEntry.fromLeaseSet(ls, nick);
|
||||
ret.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deliverResult(List<NetDbEntry> data) {
|
||||
if (isReset()) {
|
||||
// The Loader has been reset; ignore the result and invalidate the data.
|
||||
if (data != null) {
|
||||
releaseResources(data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Hold a reference to the old data so it doesn't get garbage collected.
|
||||
// We must protect it until the new data has been delivered.
|
||||
List<NetDbEntry> oldData = mData;
|
||||
mData = data;
|
||||
|
||||
if (isStarted()) {
|
||||
// If the Loader is in a started state, have the superclass deliver the
|
||||
// results to the client.
|
||||
super.deliverResult(data);
|
||||
}
|
||||
|
||||
// Invalidate the old data as we don't need it any more.
|
||||
if (oldData != null && oldData != data) {
|
||||
releaseResources(oldData);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
if (mData != null) {
|
||||
// Deliver any previously loaded data immediately.
|
||||
deliverResult(mData);
|
||||
}
|
||||
|
||||
// Begin monitoring the underlying data source.
|
||||
mMonitor = new NetDbMonitor();
|
||||
mHandler.postDelayed(mMonitor, 50);
|
||||
|
||||
if (takeContentChanged() || mData == null) {
|
||||
// When the observer detects a change, it should call onContentChanged()
|
||||
// on the Loader, which will cause the next call to takeContentChanged()
|
||||
// to return true. If this is ever the case (or if the current data is
|
||||
// null), we force a new load.
|
||||
forceLoad();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStopLoading() {
|
||||
// The Loader is in a stopped state, so we should attempt to cancel the
|
||||
// current load (if there is one).
|
||||
cancelLoad();
|
||||
|
||||
// Note that we leave the observer as is. Loaders in a stopped state
|
||||
// should still monitor the data source for changes so that the Loader
|
||||
// will know to force a new load if it is ever started again.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onReset() {
|
||||
// Ensure the loader has been stopped.
|
||||
onStopLoading();
|
||||
|
||||
// At this point we can release the resources associated with 'mData'.
|
||||
if (mData != null) {
|
||||
releaseResources(mData);
|
||||
mData = null;
|
||||
}
|
||||
|
||||
// The Loader is being reset, so we should stop monitoring for changes.
|
||||
if (mMonitor != null) {
|
||||
mHandler.removeCallbacks(mMonitor);
|
||||
mMonitor = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCanceled(List<NetDbEntry> data) {
|
||||
// Attempt to cancel the current asynchronous load.
|
||||
super.onCanceled(data);
|
||||
|
||||
// The load has been canceled, so we should release the resources
|
||||
// associated with 'data'.
|
||||
releaseResources(data);
|
||||
}
|
||||
|
||||
private void releaseResources(List<NetDbEntry> data) {
|
||||
// For a simple List, there is nothing to do. For something like a Cursor, we
|
||||
// would close it in this method. All resources associated with the Loader
|
||||
// should be released here.
|
||||
}
|
||||
|
||||
private class NetDbMonitor implements Runnable {
|
||||
public void run() {
|
||||
// There is no way (yet) to monitor for changes to the NetDB,
|
||||
// so just force a refresh every 10 seconds.
|
||||
onContentChanged();
|
||||
mHandler.postDelayed(this, 10 * 1000);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user