The point is that from Activity A to B I need to create Activity B every time, but I don't close Activity A because when I return to Activity A from B, I simply finish Activity B but I don't create Activity A because I didn't finished it. That is what I want.
The problem is when I try to pass data and objects from Activity B to A. I can't use intents and putExtra() because I don't start Activity A, I simply resume it with onResume().
SharedPreferences don't let me to pass objects so does anyone knows if there's any method to pass objects from B to A?
SOLUTION: http://www.javatpoint.com/android-startactivityforresult-example
Thanks to #brightstar #ThMBc #Avtar Guleira #Edy Bolos that's was I looking for :)
You can start activity B using startActivityForResult, and then return from it to A your data inside intent. You can find example on it here:
http://developer.android.com/reference/android/app/Activity.html
There are different methods for different cases. If the object created in B is going to be used application wide, you might consider giving it to the appliction, so that every activity can reach it by
.getAppliction().getMyField()
Note that using a static field in a general class almost comes down to the same thing, but this follows the rules of encapsulation.
If B is launched purely for the creation of the resulting object then starting an activity for result is the way to go, as brightstar said:
.startActivityForResult()
as documented in the android dev docs
Technically you can also pass objects through sharedPrefs if you serialize them (e.g. converting them to a json object and passing a string in prefs), but that is not really the way one would do this.
Yes you can do it.
For Example:
Create a standalone java class
Class C {
public static ArrayList<YourObject> myList;
}
Import the C class header
enter code here
Class B {
myList.add()
}
import C class header
Class A{
myList.get(index)
}
Use an Singleton-Class to store and retrieve objects.
public class Model {
private static Model model = null;
private Object myObject;
private Model() {}
public static Model getInstance() {
if (model == null) {
model = new Model();
}
return model;
}
public Object getMyObject(){
return myObject;
}
public setMyObject(Object myObject){
this.myObject = myObject;
}
}
When you are in Activity A you store the objects you need in the model and retrieve them afterwards in activity B
You can create another Class and create static properties which will hold your objects for you. Please look.
Class Utils {
public static MyObject object;
public static int index;
}
Use it like
Utils.object = new MyObject();
Utils.index = 4;
You cann't transfer object as per you scenario because you are not calling Activity A directly(means startactivity).You can achieve this scenario in another way. You have to set/save data in Application class from Activity B and then you can get data from application class in activiy A onResume() method and do whatever you want.
Follow below steps:
Just start Activity B using startActivityForResult method instead of
startActivity
Then override onActivityResult in your Activity A.
When you want to finish or onBackPressed Activity B. just pass data using intent
in setResult Method
For complete documentation you can view this link:
Getting a Result from an Activity
So, when ever Activity B will finished OnActivityResult will be called of Activity A. In this method you will get Intent that you have set from Activity B. You can whatever you wan to do man then.
Please just don't use static fields!!! It really bad practice, and you can encounter concurrency issues.
You can easily accomplish your request by starting activity B with startActivityForResult, and then in activity B you can catch the result by overriding onActivityResult method, like described here: http://developer.android.com/reference/android/app/Activity.html#StartingActivities
Related
I have two classes named abc and def. Class abc has string named "paths" and function named "test". I can easily use the variable "paths" from another class "def" but can't seem to call the function "test" from class "def".
I have created an object of class abc in class def and tried to call the function but it doesn't work.
public class abc extends Activity {
String paths="path";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
test("lol");
}
public void test(String name){
Toast.makeText(abc.this,name,Toast.LENGTH_LONG).show();
}
}
public class def extends Activity {
abc x= new abc();
String paths=x.paths;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toast.makeText(def.this,paths,Toast.LENGTH_LONG).show();// This is
//working
x.test("hahahas"); // Not working
}
}
i want the method "test" from class abc to be used by class def passing parameter from class def.
The problem is this
abc x= new abc();
You shouldn't be creating an instance of something that extends Activity in this way. You should be using startActivity or startActivityForResult
Also, you shouldn't be holding a reference to one activity inside an instance of another one at all, because activities are created and destroyed by Android so the reference you hold to it may go stale. See Android Activity Lifecycle`. Simply rotating your device is enough to make this happen.
From the tutorial "build your first app" we have start another activity, assuming that you do infact want to launch another activity. You need to learn about intents; let me quote from that link:
An Intent is an object that provides runtime binding between separate components, such as two activities. The Intent represents an app’s "intent to do something."
Thanks for all your comments. I found the solution. In class def, instead of extending Activity i used
public class def extends abc
making class "def" child class of "abc". And after the line
super.onCreate(savedInstanceState);
in class "def" i added one line shown below which did the job.
super.test("lol123");
Are the classes in the same package? (I assumeing that they are in the same package, because you dont have public infront of String paths)
If a method is public you should be able to call it from everywhere.
So i guess you have a problem in your test case.
try with classes, that do not extend Activity and only have the methods needed to test. Then extend your testcase further and further until it stops working.
Is the path variable final?
you might want to add public static final modifier to it.
The first problem is i have java class with 500 lines. That will so bad, so i want to split them. I found solution in another stackoverflow thread that, we can pass main class context to another class.
//main class
Public class Main{
#Override
Public void onCreate(Bundle inst)
{
Super.onCreate(inst);
ClassB bclass = new ClassB(this);
bclass.setLayout();
}
}
//B class
Public class ClassB{
Activity act1;
Public ClassB(Activity act)
{
act1 = act;
}
Public void setLayout()
{
this.act1.setContentView(R.layout.lay);
}
}
Okay, thats work. But how to make act1 be our main context? so every time i want call setContentView from ClassB i don't need to use act1 again
Edit 1:
What i hope is, i want to make act1 as default context for ClassB. So when i call setContentView from ClassB, its directly called to Main.setContentView
Because if i just call setContentView from ClassB, i wi get NullPointerException. Its make a sense since ClassB have no context
Not sure why you are doing this. There are ways to reduce lines of a single java class instead of keeping UI references in other classes or rendering UI by other classes. You can encapsulate your business logic(Not UI) in other classes which can improve the readability of your code or in your case, if you have multiple Activities which have similar behavior, you can create a base abstract activity class and put all the base code to it.
I have one Activity and six different Fragments attached to it. Each fragment has OnFragmentInteractionListener interface and activity implements all these listeners in order to receive callbacks. It looks a little messy, so I'm interested are there some patterns/ways to simplify this and make more elegant?
A good solution could be use the SAME OnFragmentInteractionListener for all fragments, and use one param of each listener methods (like a TAG parameter) to identificate what fragment sent the action.
Here an example:
Make a new class and every fragment use this class
OnFragmentInteractionListener.java
public interface OnFragmentInteractionListener {
public void onFragmentMessage(String TAG, Object data);
}
In your activity:
public void onFragmentMessage(String TAG, Object data){
if (TAG.equals("TAGFragment1")){
//Do something with 'data' that comes from fragment1
}
else if (TAG.equals("TAGFragment2")){
//Do something with 'data' that comes from fragment2
}
...
}
You can use Object type to pass every type of data that you want ( then, in every if, you must convert Object to type that were necessary).
Using this way, maintenance is easier than have 6 differents listeners and a method for every type of data you want to pass.
Hope this helps.
My attempt at improving neonamu's answer:
You can define an interface like specified above, but a generic one
public interface OnListFragmentInteractionListener<T> {
void onListFragmentInteraction(String tag, T data);
}
Then in the host activity you can implement it specifically for the type you want, or like suggested above for Object:
public class MyFragActivity implements OnListFragmentInteractionListener<Object> {
...
#Override
public void onListFragmentInteraction(String tag, Object data) {
//do some stuff with the data
}
}
This way when you implement the interface depending on your application's needs, maybe you can reuse this interface in another situation.
I currently have a parent class which has two subclasses and what I essentially want to do is have them both inherit a shared variable (a float). I need to set the value of the float in subclass1 and then use the value of the float in subclass2. I should add that these are all android activities and that subclass1 is at the beginning of a chain of activities and subclass2 is at the end of this chain, all the activities in between are also children of the same parent class.
What I currently have is something similar to the following:
(I've left a lot of the other code out this is just the bare bones)
class activityParent extends Activity{
public static float value;
public void setValue(){
//grab the value from phone (ill leave this code out and will hardcode a value below as an example)
value = 0.6f;
}
public void useValue(){
//where i use the value in another function here
otherFuncion(value);
}
}
class subclass1 extends activityParent
{
#Override
public void onCreate(Bundle bundle){
setValue();//need this to be initialized first
super.onCreate(bundle);
}
}
class subclass2 extends activityParent{
//some previous code here
//i need to use the value just before the activity finishes
useValue();
finish();
}
That float value is never used anywhere else.
This approach just seems wrong and I know it but I'm not sure how to go about implementing this properly.
I was thinking about passing data with intents but as mentioned the two subclasses arent in direct contact with each other, theres a series of activities between them and I'd rather not have to string this data through them all just to reach the end.
There is FAQ discussed in below link.
How do I pass data between Activities/Services within a single application?
Ideally, since you want to share a primitive data type (a float), Intent is recommended. But since this does not fit well with your requirement, you may skip this.
Next, using "static" (which you are currently doing) is also fine. You can access these static fields from any other class in your application.
But, if you want to have an alternate, then "Singleton" class can be used. This is a class that is designed to have only one instance.
public class Singleton {
private static Singleton INSTANCE ;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(INSTANCE == null){
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
It has a static method with a name such as getInstance() that returns the instance; the first time this method is called, it creates the global instance.
For example activity subclass1 may retrieve the instance and call setValue(0.6); later activity subclass2 may retrieve the instance and call getValue() to retrieve the last set value.
Be very carefull with a cascade of classes. The onCreate() of a SubClass1 calls super.onCreate() which is the onCreate() of ActivityParent. This may trigger a chain reaction (the intent calling ActivityParent is still available to onCreate()).
Providing finish() and this.finish() in onPause() or onStop() method is same?
Yes. Please become familiar with meaning of this. -> it's value is the reference to the current object. For example, if you have a class named Foo, and it has method named method(), then this in it would be a reference to a instance of the Foo (that is: a Foo object). Usually you do not need to use this.
this in any context refers to the containing class. So, if you are using the method inside an Activity, then this.finish() is same as finish(). However, if you are using this in a different class type, you may not have this.finish()
Even though the question is 3 years old.I prefer to torch some light over the present and future researchers.
this is just an object reference.You don't have to use this every time ,other than you need to get a reference of parent class from a child class instance.
Let's consider an example when using Thread class.
public class A
{
public A()
{
new Thread(new Runnable()
{
public void start()
{
B child=new B(A.this);//In this scenario,'A.this' refers to the parent class 'A' in which the 'Thread' class instantiated.If you simply pass 'this' ,then it would refer to the 'Thread' class as this statement executed in the current scope.
}
}).start();
}
}
public class B
{
A parent;
public B(A parent)
{
this.parent=parent;//'this' refers to the class B ,so that it can access the global variable 'parent' ,then assigns it with the local variable 'parent' passed through the constructor.
}
}
Like listed above ,there are different usages of this keyword.Its better to refer the oracle's documentation over here https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
finish() and this.finish() is the same.
For the other part of the question, please read about the Activity lifecycle.
In your case It's the same. It's sometimes important to use this->... if you have an member and an method parameter with the same name like in the following example:
class foo{
int number;
void setNumber(int number);
}
so you can write in your method
void foo::setNumber(int number)
{
this->number = number;
}
And so It's clear which element you have used. But be careful don't use the same names it's not really nice.