Sending back data from activity to already running activity - android

I have an activity Detail that start a new activity List via Intent.
In List I do stuff and then I need to pass some data back to Detail.
The stack, before calling back from List, should contain Detail (on Pause) and List (running).
The data I need to pass back are an ArrayList<MyObject>, where MyObject implements Parcelable (and all its needed methods), so I can use
intent.putParcelableArrayListExtra("myList", myListOfParcelableObjects);
to send data via Intent.
The problem now is on the called activity, Detail.
I've tried to catch the new intent via onNewIntent(Intent intent) and onResume(..) method, but the first (even using setIntent(intent)) and the second doesn't get the new intent sent from List and the data contained in intent.
How can I get the new intent in Detail, manage new datas and "resume" Detail as it was before calling List?

create a Singleton Manager save the Data there and use the data when needed.
public class DataManager {
private static DataManager instance = new DataManager();
private int mData;
private DataManager() {}
public static DataManager getInstance() {
return instance;
}
public void setData(int number) {
mData = number;
}
public int getData() {
return mData;
}
}
Activity A
DataManager manager = DataManager.getInstance();
manager.setData(1);
Activity B
DataManaget manager = DataManager.getInstance();
int data = manager.getData();
this is an Example.
Hope it helps.

You can use Singleton class for storing common data. Hope it will help.

Related

remove static varialble android service

There is android application which stored data into the sqlite. I keep a list of routes in databases table.I display the data on the active route on the screen/To release the processor, I use static List inside service.To release the processor, I use static List inside service. I change the list when receiving data from the server.
public class NetworkService extends Service{
private static NetworkService instance = null;
private static List<RouteTask> routeTaskList;
private static LoadRoutesTask loadRoutesTask;
private static RouteChangedListener rtListener ;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
if (instance == null) {
instance = this;
NetworkManager.updateNetworkInfo(this);
NetworkManager.setNetworkListener(this);
}
}
public static Context getCurrentContext() {
return instance;
}
public static boolean hasInstance() {
return instance != null;
}
public static void setRouteTaskList(List<RouteTask> rtList)
{
routeTaskList = rtList ;
}
public static List<RouteTask> getRouteTask(){
return routeTaskList;
}
}
In application i can set value
NetworkService.setRouteTaskList(list);
or get value :
List<RouteTask> = NetworkService.getRouteTaskList();
My application usually use routeTaskList instead of sql query for data table.
The task now is change the service, for the android development standards. I removed static field and Now, I run a service through intents (startService(intent)). How Can I remove static settter and getter for routeTaskList object ?
You can provide the Service with the list of tasks as extras in the Intent you use in the startService() call. This replaces your static setter.
To get the list of tasks is more complicated. Options:
You could use AIDL and bind to the Service and then call a method to get the list of tasks
You could call startService() with an Intent that asks the Service to broadcast the list of tasks. In the Service.onStartCommand() you could then send a broadcast Intent which contains the list of tasks as extras.
You could have the Service send a sticky broadcast Intent which contains the list of tasks every time the list changes. Your app would then use registerReceiver() call to read the most recently sent sticky broadcast.

How to pass a value to an activity from another WITHOUT starting it?

I want to pass a value from activity A to activity B without actually starting the activity B (therefore this rules out the use of Intents and putExtra). The activity B may or may not be started but when it does it needs to display the value passed to it by activity A.
I searched high and low but couldn't find any relevant solution to this seemingly simple question. Any help will be appreciated!
You can't find a solution, because it's something that goes against any logic.
Activity B can't do anything if not started and visible. Activity B might even already be destroyed by the system without you knowing.
You can use a lot of things to set some variables, which your Activity B can read such as in your Application, somewhere in your XML or simply any random class.
Still, you can not actually DO anything with any of these options, until you start Activity B and when you can, it will just effectively be the same as giving the extra data in the Intent.
Use global class like :
public class AppConfig {
Context context;
public AppConfig(Context mxt) {
context = mxt;
}
public static String filepath = null;
Then, in activity A before onCreate() :
AppConfig config;
Context context;
and in onCreate() method put this :
context = getApplicationContext();
config = new AppConfig(context);
And, in second Activity B before onCreate() :
AppConfig config;
Context context;
And, in onCreate() method put this :
context = getApplicationContext();
config = new AppConfig(context);
And set the value where you want. Hope this will help you.
You can use shared Preferences. Using this one Activity can set Value into it, and other activity can read from it.
So you need to keep a value for an activity . If it starts it means you have to use those values, otherwise you will discard those values. For this you can use a separate class with a variable of datatype that you want and you can create getter setter for that and you can use it.
Make use of the classes
public class GetSet {
public GetSet() {
super();
}
private static boolean passwordSet = false;
public static boolean isPasswordSet() {
return passwordSet;
}
public static void setPasswordSet(boolean passwordSet) {
GetSet.passwordSet = passwordSet;
}
}
You can access ths using GetSet.setPasswordSet(false);
and Boolean flag = GetSet.isPasswordSet();
Set the value as Global:
public class Global {
public static int mValue;
public static int getValue() {
return mValue;
}
public static void setValue(int mValue) {
Global.mValue = mValue;
}
}
I was looking for answers to that but I couldn't find it. So I found a way to do that.
First Activity
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("Flag" , true);
startActivity(intent);
Second Activity
boolean flag;
flag = getIntent().getBooleanExtra("Flag" ,false);
if(flag == true)
{
this.finish();
}
So now you may send any data you want it will open the Second Activity and then immediately close it after you wouldn't even realize it. You may use Shared prefences to save your data for after usage.

How to send List instance to another activity?

I have class :
public class ClassList
{
private String Language1;
private String Language2;
public ClassList(String Language1,String Language2)
{
this.Language1 = Language1;
this.Language2 = Language2;
}
public String Language1()
{
return this.Language1;
}
public String Language2()
{
return this.Language2;
}
}
I would like to send ArrayList to another activity by using an instance of this class. Is this possible?
I would like to send ArrayList to another activity by instance using.
It is possible?
Assuming you mean, sending the ClassList to another Activity by using an Intent, you
have to look at the Parcelable interface:
Here's a nice example of how to do it

How to reference the current or main activity from another class

I often find myself needing to access methods that require referencing some activity. For example, to use getWindowManager, I need to access some Activity. But often my code for using these methods is in some other class that has no reference to an activity. Up until now, I've either stored a reference to the main activity or passed the context of some activity to the class. Is there some better way to do this?
If you already have a valid context, just use this:
Activity activity = (Activity) context;
Passing context is better way for refrence Activity.
You can pass Context to another class.
IN Activity ::
AnotherClass Obj = new AnotherClass(this);
IN Another Class
class AnotherClass{
public AnotherClass(Context Context){
}
}
You can implement the necessary methods in your activity and implement a Handler. Then, simply pass a handler instance to your classes, where you can obtain a message for handler and send it to target.
You can make you application instance a singleton, and use it when you need a Context
An example is in this question:
Android Application as Singleton
This way, when you need a Context, you can get it with
Context context = MyApplication.getInstance()
This might not be the cleanest solution, but it has worked well for me so far
I found a way to get the Activity to a non-activity class that I have not seen discussed in forums. This was after numerous failed attempts at using getApplicationContext() and of passing the context in as a parameter to constructors, none of which gave Activity. I saw that my adapters were casting the incoming context to Activity so I made the same cast to my non-activity class constructors:
public class HandleDropdown extends Application{
...
public Activity activity;
...
public HandleDropdown() {
super();
}
public HandleDropdown(Activity context) {
this.activity = context;
this.context = context;
}
public void DropList(View v,Activity context) {
this.activity = context;
this.context = context;
...
}
After doing this cast conversion of Context to Activity I could use this.activity wherever I needed an Activity context.
I'm new to android so my suggestion may look guffy but what if you'll just create a reference to your activity as private property and assign that in OnCreate method? You can even create your CustomActivity with OnCreate like that and derive all your activities from your CustomActivity, not the generic Activity provided by android.
class blah extends Activity{
private Activity activityReference;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityReference = this;
}
}
after that you could use that the way you want, i.e. in
Intent i = new Intent(activityReference, SomeOtherActivity.class)
etc
There are many ways for Activities communication.
you can use:
the startActivityForResult method
a system of broadcast message and receiver (you can broadcast an event from the actual activity, and register a receiver in the target activity. Remember that the target activity must be previously initialized and non finished)
as you say, store a reference of the target activity wherever you need.
We built a framework for this. We have a BaseActivity class that inherits from Activity and it overrides all the lifecycle methods and has some static (class) variables that keep track of the activity stack. If anything wants to know what the current activity is, it just calls a static method in BaseActivity that returns the activity on top of our privately-managed stack.
It is kinda hacky, but it works. I'm not sure I would recommend it though.
Handle the Intent in the class you want to do these methods, and send your information to it in a Bundle like so:
Intent i = new Intent("android.intent.action.MAIN");
i.setComponent(new ComponentName("com.my.pkg","com.my.pkg.myActivity"));
Bundle data = new Bundle();
i.putExtras(data);
startActivityForResult(i);
Then use an OnActivityResultListener to grab the new data.
I solved this by making a singleton class has an instance of the class below as a member.
public class InterActivityReferrer <T> {
HashMap<Integer, T> map;
ArrayList<Integer> reserve;
public InterActivityReferrer() {
map = new HashMap<>();
reserve = new ArrayList<>();
}
public synchronized int attach(T obj) {
int id;
if (reserve.isEmpty()) {
id = reserve.size();
}
else {
id = reserve.remove(reserve.size() - 1);
}
map.put(id, obj);
return id;
}
public synchronized T get(int id) {
return map.get(id);
}
public synchronized T detach(int id) {
T obj = map.remove(id);
if (obj != null) reserve.add(id);
return obj;
}
}
This class can get a T object and return a unique integer assigned to the object by attach(). Assigned integers will not collide with each other unless HashMap fails. Each assigned integer will be freed when its corresponding object is detached by detach(). Freed integers will be reused when a new object is attached.
And from a singleton class:
public class SomeSingleton {
...
private InterActivityReferrer<Activity> referrer = new InterActivityReferrer<>();
...
public InterActivityReferrer<Activity> getReferrer() {return referrer;}
}
And from an activity that needs to be referred:
...
int activityID = SomeSingleton.getInstance().getReferrer().attach(this);
...
Now with this, a unique integer corresponding to this activity instance is returned. And an integer can be delivered into another starting activity by using Intent and putExtra().
...
Intent i = new Intent(this, AnotherActivity.class);
i.putExtra("thisActivityID", activityID);
startActivityForResult(i, SOME_INTEGER);
...
And from the another activity:
...
id refereeID = getIntent().getIntExtra("thisActivityID", -1);
Activity referredActivity = SomeSingleton.getInstance().getReferrer().get(refereeID);
...
And finally the activity can be referred. And InterActivityReferrer can be used for any other class.
I hope this helps.
public static Activity getLaunchActivity()
{
final Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
final Method methodApp = activityThreadClass.getMethod("currentApplication");
App = (Application) methodApp.invoke(null, (Object[]) null);
Intent launcherIntent = App.getPackageManager().getLaunchIntentForPackage(App.getPackageName());
launchActivityInfo = launcherIntent.resolveActivityInfo(App.getPackageManager(), 0);
Class<?> clazz;
try
{
clazz = Class.forName(launchActivityInfo.name);
if(clazz != null)
return Activity.class.cast(clazz.newInstance());
}
catch (Exception e)
{}
return null;
}
Just a guess since I haven't done this but it might work.
1) Get your applicationContext by making your Android Application class a Singleton.
2) Get your ActivityManager class from the context.
3) Get a list of RunningTaskInfos using getRunningTasks() on the ActivityManager.
4) Get the first RunningTaskInfo element from the list which should be the most recent task launched.
5) Call topActivity on that RunningTaskInfo which should return you the top activity on the activity stack for that task.
Now, this seems like a LOT more work than any of the other methods mentioned here, but you can probably encapsulate this in a static class and just call it whenever. It seems like it might be the only way to get the top activity on the stack without adding references to the activities.

Regarding Intents

According to what i have learnt from passing data using Intents is that when you pass Object O from Activity A to Activity B via intents, activity B receives a COPY of object O. The way things work is that The object O gets serialized (converted to a sequence of bytes) and that sequence of bytes is then passed to Activity B. Then activity B recreates a copy of object O at the moment it was serialized.
I would like to know if it would be efficient if one extends the Intent class to create a custom Intent and have references to the objects that are required by the other activities and pass the data to the other activities. For example:
public class CustomIntent extends Intent {
private Object o;
public CustomIntent() {
super();
// TODO Auto-generated constructor stub
}
public Object getObject () {
return o;
}
public void setObject(Object object) {
this.o = object;
}
}
In the receiving activity i get the intent and cast the intent to the CustomIntent type and retrieve the object required by the activity. Would this improve the efficiency by reducing the need for Serialization? Kindly throw some light on this. Thanks in advance.
No. Intents are dispatched by the Android system and are always serialized as they can be sent to any activity, service, etc in the system.
For your problem you could probably workaround this issue by creating an Application class and storing your data in it:
class CustomApplication extends Application {
private Object data;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
You activate it by updating AndroindManifest.xml setting the android:name property on the application tag you your class name.
To use in your activities:
CustomApplication app = (CustomApplication) getApplicationContext();
app.setData(yourDataObject);
I think it would be better if you let the android handle everything for you. Do not customize it, if it is not very essential.
If you want to have the reference of the object in another activity then there are other ways too.
You can make your object static and directly access it from other activity.
You can make a new object of same type and replace it after coming again back to the first activity(in onActivitResult() method.).
or there may be many more ways to do it.
Thanks.

Categories

Resources