I am a newbie, trying to execute 2 url queries on the same activity in Android.
I managed to get it done using two different AsyncTasks running in parallel.
Both url queries have separate classes and query classes - its two different websites with different data. However i wanted to display it on one screen - one activity.
I initiated both my Loaders with separate loaderIDs
private static final int LOCAL_LOADER_ID = 1;
private static final int GLOBAL_LOADER_ID = 2;
Then i initiated both the loaders . . . .
LoaderManager loaderManager = getLoaderManager();
loaderManager.initLoader(LOCAL_LOADER_ID, null, new LocalLoaderClass());
loaderManager.initLoader(GLOBAL_LOADER_ID, null, new GlobalLoaderClass());
and created the LoaderCallbacks for both of them, so this is an example of the first one one, the second one is the same:
private class GlobalLoaderClass implements
LoaderManager.LoaderCallbacks<GlobalData>
{
#Override
public Loader<GlobalData> onCreateLoader(int i, Bundle bundle) {
return new GlobalDataLoader(this, CMC_REQUEST_URL);
}
and so on . . . . . . with the remaining Override methods
However i keep getting an error on the method, i think i am missing something.
I have implemented the GlobalDataClass(Context, URL)
Related
This is a continuation from the question I 1st asked here, Creating a new ArrayPagerAdapter with variety of Fragments. You were dead on about me using the wrong ArrayAdapter I just needed to use the one that has v4 support. I have posted the code for it below. One of the next blocks i'm getting stuck on right now is creating the PageDescriptor objects in the ArrayList passed into SimplePageAdapter. I've tried copying and pasting the SimplePageDescriptor class used in the Demo into my code but I am getting an error when trying to return from the Parceable.Creator method. It says SimplePageDescriptor has private access in com.commonsware.cwac.pager.SimplePageDescriptor. I guess the main thing i'm trying to grasp is how to use the SimplePageDescriptor from the demo in my own code. Do I just use the entire pager folder? I have posted my code for the SimplePagerAdapter and the SimplePageDescriptor below.
class SimplePagerAdapter extends ArrayPagerAdapter<android.support.v4.app.Fragment> {
public SimplePagerAdapter(FragmentManager fragmentManager,
ArrayList<PageDescriptor> descriptors) {
super(fragmentManager, descriptors);
}
#Override
protected Fragment createFragment(PageDescriptor desc) {
mMainFragment = JudgeMainFragment.newInstance();
mClassifyFragment = JudgeClassifyFragment.newInstance();
mSidebarFragment = JudgeSidebarFragment.newInstance((SidebarCall) mActivity);
mVerdictFragment = JudgeVerdictFragment.newInstance();
return (mMainFragment.newInstance());
}
}
public static final Parcelable.Creator<com.commonsware.cwac.pager.SimplePageDescriptor> CREATOR=
new Parcelable.Creator<com.commonsware.cwac.pager.SimplePageDescriptor>() {
public com.commonsware.cwac.pager.SimplePageDescriptor createFromParcel(Parcel in) {
//This is the line I get the error at
return new com.commonsware.cwac.pager.SimplePageDescriptor(in);
}
public com.commonsware.cwac.pager.SimplePageDescriptor[] newArray(int size) {
return new com.commonsware.cwac.pager.SimplePageDescriptor[size];
}
};
One of the next blocks i'm getting stuck on right now is creating the PageDescriptor objects in the ArrayList passed into SimplePageAdapter
PageDescriptor is an interface. Create your own class (e.g., BlainePageDescriptor) that implements the interface. This is covered in the documentation.
I've tried copying and pasting the SimplePageDescriptor class used in the Demo into my code
That will not solve your problem.
Your problem, as I understand it, is that you want your ArrayPagerAdapter to be able to handle N different types of pages (JudgeMainFragment, JudgeClassifyFragment, etc.). That requires you to return the proper fragment from createFragment(), given the supplied PageDescriptor. Hence, you need to create your own PageDescriptor implementation (e.g., BlainePageDescriptor). That class needs to hold onto sufficient information to both satisfy the PageDescriptor interface and be able to tell createFragment() what sort of fragment to create.
Whenever I design an Android Activity that is called with startActivityForResult I always find myself blurting out any number than comes to mind and using it as the request code.
Is there a specified pattern or numbering scheme I should follow for these request codes?
(ps: Should I move this to a different Stack Exchange page?)
It depends on you, I use this pattern, example:
class MainActivity extends Activity {
public static final int REQUEST_CODE_PHOTO = 1;
public static final int REQUEST_CODE_CROPPER = 2;
//code
}
My MainActivity calls another Activity A which needs to access some members of MainActivity.
What is the best way to send a reference to Main Activity (or its context) to Activity A without resorting to complicated methods like parcelables etc?
There are some heavyweight android wrestling matches here but I am not sure that it is relevant to my problem.
details
I have Alert and Alerted objects in a one-to-many relationship (Alerted represents the various times an Alert was rung).
AlertsListActivity extends ListActivity which displays a list of Alert objects from a SQLite database table (primary key: alertId). It has an AlertsListAdapter.
AlertedsListActivity has a ListFragment which displays a list of Alerted objects from Alerted table (foreign key is alertId from Alert table).
It has an AlertedsListAdapter.
AlertsListActivity needs to call AlertedsListActivity to display the list of Alerted objects. I used startActivityForResult().
Inside AlertedsListAdapter
public View getView(int position, View convertView, ViewGroup parent) {
final Alert alertItem = (Alert) mainActivity.alertsListAdapter.getItem(position);
final Alerted alertedItem = (Alerted) getItem(position);
...
I do need the Alert objects also, in order to display some identifying information from them with each Alerted list item. Hence I need the reference to mainActivity.alertsListAdapter
How can AlertedsListActivity access AlertsListActivity?
Update: Since I did not get any solutions, I implemented a workaround. The data that I needed to access from Main Activity, I modified. So the Alert object was made a parcelable, and the SQLOpenHelper was made a singleton.
This allows the data to be accessed from Activity A.
Here's the simple, common way to do it:
singletons typically have variables like the below example, "useThisContext" or "mainFeedIsHere".
public class Cloud
{
private static Cloud ourInstance = new Cloud();
private Cloud() { Utils.Log("cloud singleton launched"); }
public synchronized static Cloud getInstance()
{
return ourInstance;
}
/////////////////////////////////////////////////
public Context useThisContext;
another example ...
public class Feed
{
private static Feed ourInstance = new Feed();
private Feed()
{
Utils.Log("feed singleton launched");
freshestPostsForDisplay = new ArrayList<ParseObject>();
}
public synchronized static Feed getInstance()
{
return ourInstance;
}
public List<ParseObject> freshestPosts;
public MainActivity mainFeedIsHere;
Quite simply when everything launches (or when it changes), those "things" need to set those variables in the singleton. In other words, those things "tell the singleton, where they are." It's that simple.
So, in the MainActivity perhaps, in onCreate, it might say something like...
CLOUD.useThisContext = this;
FEED.mainFeedIsHere = this;
Then for example inside Feed.java you may have say
mainFeedIsHere.feedReload();
It goes without saying you have to check that they are not null (but how else could it be?) and you have to keep them up-to-date as it were. (i.e., for whatever reason you may want to change "useThisContext" -- again how else could it be?)
{Sometimes you'll have one "centralised" singleton .. perhaps "State" .. to sort of combine all these together - so that anyone can "get to" any of those "exposed" things as needed. This is, really, how game engines go; so that you can say more or less SoundEffects.Booms() or Tanks.Faster() or AI.FindVillains() at any time anywhere.}
Cheers!
Since I did not get any solutions, I implemented a workaround. The data that I needed to access from Main Activity, I modified. So the Alert object was made a parcelable, and the SQLOpenHelper was made a singleton.
This allows the data to be accessed from Activity A.
I am writing an app for android that connects to a server to get/post some xml data. I currently have a small class with static methods such as post(string URI, string body) and get() that wrap the httpclient calls to create a http post request and return the response. I am wondering if i should also have these method work in their own threads. Currently, i need to do a async task to call my Helper.post(..) method to connect to and get a request from a server. Is it better to just have the async stuff incorporated in the helper class to avoid having multiple repeated async tasks all across my app to just make post calls?
As a general principle it is best to wrap up repeated code so that you dont continually re-invent the wheel. Therefore if it is possible for you to wrap up the threading easily then it would be a good idea to do so.
This is not always very easy. Methods which get something from the network define want done with that data once it's been received. Usually you just return it. But if you're threading within the method then you have to push it somewhere. This leads to a lot of additional callbacks and you dont (in my experience) save much.
Rather than defining a bunch of static methods which do the threading for you, I would recommend you keep threading out of the static methods and define a bunch of abstract AsyncTasks instead. Each defines it's own doInBackground and leaves the onProgressUpdate and onPostExecute methods undefined. That way you get the best of both worlds - you re-use as much as possible (the doInBackground code) but are able to customize where the data is sent once received.
Example
Your static code:
public class MyStaticClass {
public static String getFoo( String name ) {
// use the network to get a string;
return "hello " + name; // Use your immagination.
}
}
An AsyncTask defined as public so that it can be re-used easily.
public class GetFooTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground( String... name ) {
return MyStaticClass.getFoo(name[0]);
}
}
Now to use it. Your static library or public async task could not have known what you need to do with the resulting string. So you tell it what to do with the result here:
public class MyActivity extends Activity {
#Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_view);
// You've already defined how to get the data
// so using it requires only minimal code now.
GetFooTask titleTask = new GetFooTask() {
#Override
public void onPostExecute( String heading ) {
((TextView) findViewById(R.id.heading)).setText(heading);
}
};
titleTask.execute("John");
}
}
In this example you can use the GetFooTask in as many activities as you like, just tell it where to put the data each time.
If you really think you will never want to do two network tasks on the same thread then you can combine the static code and the "abstract" AsyncTask. But more often than not I find I want to fire several things to and from the network before I finally return a result. If I did the threading in the network static code I would end up firing 10 threads for one request... therefore I keep threading out the static code.
I have an activity which uses two Loaders. Each of them returns different type of data. To get data from a single Loader one just implements LoaderCallbacks<D> into an Activity. I guess I could just implement LoaderCallbacks<Object> and check the type of the object and then decide which of the two LoaderCallbacks it is, but it seems like a hack to me (mostly because of the lack of type safety here).
So I thought about making the LoaderCallbacks object a static inner class, something like this:
private static class geocoderLoaderCallbacks implements LoaderCallbacks<List<Address>>{
#Override
public Loader<List<Address>> onCreateLoader(int arg0, Bundle arg1) {
GeocoderTask loader = new GeocoderTask(context, "");
return loader;
}
#Override
public void onLoadFinished(Loader<List<Address>> loader, List<Address> data) {
// TODO Auto-generated method stub
}
#Override
public void onLoaderReset(Loader<List<Address>> loader) {
// TODO Auto-generated method stub
}
}
And then using lm.initLoader(0, null, geocoderLoaderCallbacks).
Two question arise: is it ok to do, or should I rather stick to implementing LoaderCallbacks into Activity? And how do I safely pass the context into the onCreateLoader? Should I just make a constructor in geocoderLoaderCallbacks and pass the context there like this lm.initLoader(0, null, geocoderLoaderCallbacks(this))?
There is a similar question here LoaderManager with multiple loaders: how to get the right cursorloader but it doesn't explain how to manage two loaders with different data types.
It is always ok to move code away from a potentially giant class and it's much cleaner to do it with different classes then with one that can handle everything. You might even want to make them real external classes instead of inner classes if you feel that your Activity has too much code inside. LoaderCallbacks is an interface so you can and mostly should implement it in it's own class.
Passing the Context in the constructor is fine as long as you don't keep static or otherwise cached references to it.