How to execute something in an activity from a non-activity class? - android

I am executing something in an async class(from activity A), and before the result comes I start another activity B.
Now I want to execute a block of code in B based on result from the async class.
I couldn't find a proper solution over the internet. Thus posting it here.

Define your own MyApp extends Application class and declare it in your manifest as <application android:name="mypackage.MyApp></application>
Then have a public field myResult in your My App. Then you can store your result and get your result from that public field as ((MyApp)getApplication()).myResult
This is because MyApp singleton object exists all the time your app is running.
If you want notification you can use an event bus such as Otto
Or you can just send a broadcast and catch it by a broadcast receiver in your other activity..

There are a lot of possible solutions to do this. Let me add my favourites:
Event Bus (Square's Otto or GreenDroid's one). In this case you need to subscribe your activity to get the result.
Loaders - native android solution, no libs needed. To cook this one you need to use content provider, which contains the table with results and in your async task there should be a method to insert result into db.

Related

Can a service access a variable within an Activity?

I have an Activity called MainActivity that starts a Service called MainService. It is also binds the Service, so MainActivity can access methods and public variables within MainService. Is it possible to do it the other way round, i.e. the Service is able to access the Activity's methods?
I wish to implement it this way because I have a variable in MainActivity that is set upon onResume(), and on first startup the service has not yet started by the time onResume() runs, so at that point in time the service is still null.
This answer assumes that the Service in question runs in a different process:
Yes, it is possible. The general idea is that not only your Activity binds the remote Service through some AIDL defined interface, but it also implements additional AIDL interface which the Service is aware of, and sets itself as a callback target of the remote Service.
You'll have to have 2 AIDL files: the first one describes the interface of the Service, and the second one describes the interface of the Activity.
The implementation of such a scheme is very similar to "remote Service callbacks" described in this answer, though "callback" method would no longer be void, but return the value you're interested in.
Design considerations:
The above scheme will allow you to get values from Activity, but I don't think you should take this path. From the description of your use case, it looks that you only want to pass some value to the Service when Activity gets resumed. Since your Service is bound anyway, you can simply add a method setSomeValue(int value) to its AIDL definition and call this method from onServiceConnected() callback.
Yes it's possible.
You have to prepare method in your service to return back your activity just after service is bound:
public void bindActivity(MyActivity activity){...}
Then after service is bound to activity just call this method with MyActivity.this as parameter.
However...
You probably should not do it. Much more clear solution is using LocalBroadcastManager to pass events and data or use some more efficient solutions like Otto to do this same, but still - without direct access to one component's fields / methods from another.

Activity necessary for Widget?

I am new to android programming. I want to create a very simple widget in which I just have a single button and on click of that button, I want to execute some code.
My question is, is it necessary to create an activity for this?
Or can I just extend AppWidgetProvider class and write execution code in onUpdate or onReceive method?
Yes it is necessary to create a class that extends activity to accomplish interaction with a button.
In theory the provider is enough to handle appwidgets. In practice you will always need some kind of configuration, which is an Activity.
It is also very likely that the code to run, is too much for onUpdate and onReceive. At this moment you'll send Intent's out to some Actvity or Service.

How do I get return value from AsyncTask to Main Activity?

I have a class (like a helper class) -not an activity- which manages soap requests. I use this class to send soap requests that comes from activities by method doInBAckground and catch all return values from webservice by onpostexecute. Everything is ok but my problem starts at this point because I could not pass return value asynctask class to main class.
You can have some utility class available as singleton (ok, singleton is dangerous pattern
but it use is justified in android until we get sane and usabel dependency injection ) and pass result there.
Advandatges:
- no messing with intents / serialisability
- pass data or call some methid or do whatever you like
- all your activities share the same instance of singleton service.
Disadvantages:
- singleton pattern is considered dangerous
You may even go further and make your service singleton - you will start methods of it as async tasks, and then your activity may query results over dedicated methods.
Or you may go a step further - register your activity as listener in async service, and call method in this activity when ready (note: as this will be not a UI thread, you will be unable to do something with UI unless you use runOnUiThread()
Have you tried implementing the AsyncTask as an inner class of your Activity?

Sending an Activity to a non-Android class

I'm pretty much a noob when it comes to Android development. I have an Activity that has a method that pretty much just sets the text of a TextView to whatever text is provided as an argument. I have a second class, which is a Runnable, and I want to be able to give it the Activity (or obtain the Activity somehow), so it can call said method when it needs to.
This Runnable will eventually connect with a server, so it can update the application with information from the server. I've done client/server Java stuff before, so that's not the issue. I just need to figure out how to communicate between this Runnable and the Activity.
Originally, I was going to just pass the Activity itself in, but I read that it would create problems if I did. Instead, I was supposed to pass in an ApplicationContext via getApplicationContext(). I did that, but now I don't know what to do with the ApplicationContext. I tried casting it to the my Activity class, but the program just crashes.
How do I accomplish what I'm aiming at?
There are a few specific ways in Android to handle threading like AsyncTasks etc., you should read up on how to do 'painless' threading here. If it's just a one-off task where you connect to the server, get the value, set it in the TextView and then finish, I think an AsyncTask would be your best option. Continuing background processes are more suited to being services.
you can pass your activity to the constructor of your second Class like this :
public SecondClass(YourActivity _yourActivity){
this.activity = _yourActivity;
//do stuff
}
and in your Activity , you can instanciate your class like this :
SecondClass instance = new SecondClass(this);
NOTE : in your SecondClass , if you want to change the UI of your application , you can use the method runOnUiThread(Runnable);

How to send an ArrayList of custom objects in a Bundle

I have an application that uses a service to create an ArrayList of custom objects (MyObject) every x seconds. I then want my Activity to obtain this ArrayList.
I'm currently planning on having the Service send a message to the Activity's handler every time it finishes the query for the data. I want the message to the Handler to contain the ArrayList of MyObjects.
When building the method in the Activity to get this ArrayList out of the message, I noticed that I couldn't.
If I tried
msg.getData().getParcelableArrayList("myObjects")
Then the method I was passing it to that expected an ArrayList wouldn't accept it. If I tried casting the results:
(ArrayList<MyObject>)msg.getData().getParcelableArrayList("myObjects")
I received the error: Cannot cast from ArrayList<Parcelable> to ArrayList<MyObject>
MyObject implements Parcelable and I have successfully sent an ArrayList from my service to my activity by having my activity call a method on the service to retrieve it. I'm trying to go away from having my activity poll my service for this data, though.
1) How can I send an ArrayList inside the bundle in a message to handler?
2) Is there a different model I should be using to have my service update the data in my Activity that may or may not be visible? I always want the data in my activity to be the latest from the Service.
I had the exact same question and while still hassling with the Parcelable, I found out that the static variables are not such a bad idea for the task.
You can simply create a static field
public static ArrayList<MyObject> myObjects = ..
and use it from elsewhere via MyRefActivity.myObjects
I was not sure about what public static variables imply in the context of an application with activities. If you also have doubts about either this or on performance aspects of this approach, refer to:
What's the best way to share data between activities?
Using static variables in Android
Cheers.
There is another model that should be used. Another question I asked provided the answer:
Suppress notifications from a service if activity is running
As for #1, you could get around it by just removing the generics from the ArrayList declarations and casting as appropriate where needed. I know this works because that's what I did before refactoring based on the other question asked.
If the cast is the problem, just leave it be, dont cast it, the error will go away.

Categories

Resources