I am trying to pass a reference of the current activity to an object but can't seem to find a method that will do this easily. Previously I was able to do this simple passing with the "this" reference of the current context. I then changed my activity from implementing OnClickListener to creating an OnClickListener object so that I could pass it as a parameter. This is when I ran into trouble as I was trying to create the object after I clicked on a button, this means I can no longer pass the activity with "this" because "this" is now a reference of the OnClickListener.
public class MyActivity extends Activity {
private Object mObject;
private OnClickListener mListener = new OnClickListener() {
public void onClick(View v) {
Object mObject = new Object(this);
}
}
}
public class Object {
private Activity mActivity;
public Object(Activity a) {
mActivity = a;
mActivity.setContentView(R.layout.layout);
}
}
Seems like an easy fix but I can't find the answer...
Any help is greatly appreciated.
You are right, this now references the OnClickListener, as it references the current class, and you are working inside an anonymous class. You can reference the outer activity by passing mActivity.this:
Object mObject = new Object(mActivity.this);
Btw: I think I'd rename the mActivity class, as normal class naming convention is for it to start with an uppercase letter.
Add mActivity. to this
Object mObject = new Object(mActivity.this);
In your context, this refers to a listener instance, but you need the outer class's instance there, so you need to add class name to this
Related
I am trying to implement a general dialog method that every activity can call it. The public static method shall be something like this. But I have problem to cast mContent to its activity class name.
public static void openDialogEntry(Class activityClassName, Context mContext, String title, ... ) {
Dialog_Entries dialog = new Dialog_Entries( title, ... );
dialog.show( ((activityClassName) mContext).getSupportFragmentManager(), tag);
}
I want to call this method from fragments of any activity for example from a fragment(view) of SecondActivity.java using
openDialogEntry(view.getContext().getClass, view.getContext(), title, ... ) ;
What I expect to do is doing something like next line in openDialogEntry method
dialog.show( ((SecondActivity) mContext).getSupportFragmentManager(), tag);
It seems that ((activityClassName) mContext) is not working.
I want to call the public static method from MainActivity.java and ThirdActivity.java too (and their fragments which would need the casting).
How to realize this goal ?
Class has a method Class.cast(Object) that is you could do this:
public static void openDialogEntry(Class<? extends Context> activityClassName, Context mContext, String title, ...) {
Dialog_Entries dialog = new Dialog_Entries(title, ...);
dialog.show(activityClassName.cast(mContext).getSupportFragmentManager(), tag);
}
Note that cast only makes sense when providing generic information on the Class parameter
However as #Zabuzard already mentioned. This makes not much sense. If you can cast mContext to activityClassName why not use this class instead of Context as method parameter?
Context probably implements some interface or extends some class that provides the getSupportFragmentManager method. So there is no need to cast at all.
I have two classes - my main Android activity class, and my reflection class. I am using Android Studio.
In my main activity class I have one button. I want to make it so that when I press this button I should get the name of the button which is defined in strings.xml.
I don't want to use getText() so don't tell me to use it. I want to use reflection or any other good way.
In my reflection class I used reflection to get my field which I defined in my main activity class and put it into a string variable. When I show this value using a toast it's giving me a null value.
My Reflection Class
public class Reflection extends MyActivity
static public String Value;
public static void Cool() {
MyActivity myActivity=new MyActivity(); // Creating Android Main Activity Class Object
try {
Field field=myActivity.getClass().getField("btnFIRST"); //btnFirst Field Which i Defined In Android Main Activity Class
field.setAccessible(true);
Value=(String)field.get(myActivity);
}
catch (Exception E){
E.printStackTrace();
}
}
}
Android Main Activity Class
public class MyActivity extends Activity {
Reflection ref; // Here I Am Creating My Reflection Class Object
Button btnFIRST;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
btnFIRST = (Button) findViewById(R.id.btnFIRST);
ref=new Reflection(); // Reflection Class New Object
ref.Cool(); // Here I Am Calling My Cool Method Which Define In My Reflection Class
btnFIRST.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MyActivity.this, "Found Button Name="+ref.Value, Toast.LENGTH_LONG).show();
}
});
}
}
See here: +ref.Value I want to print my button value name, which is "(Click)" defined in strings.xml. But I am getting a null value instead.
I should be getting the output "Found Button Name=Click".
When you construct an instance of MainActivity, the value of btnFIRST for the instance is null. This is because btnFIRST is assigned only in the onCreate() method, which is never called on that instance.
You might think all you have to do is call onCreate() before trying to access the field, but that won't work either: you will get an exception. This is because the instance of MainActivity has not been properly set up (e.g., it doesn't have a proper Context, it does not have a Widnow, etc), so it won't be able to inflate the layout. The Android OS is responsible for doing this setup; it's not something you can do yourself. In general it is ALWAYS a bad idea to construct Activities yourself via their constructor.
That said, I can find absolutely no reason at all you would need to use reflection to obtain the text of this button. Unless you can give us a compelling reason why this would be necessary, you should just use getText().
Alternatively, if you know the string resource ID, you can call getString(...) in your Activity.
So I am using getdefaultsharedpreferences in a method called onLoadFinish (it's from a pdf library from android).
Here's the code:
public void onLoadFinish(DocumentState.OPEN state) {
//some irrelevant code here
SharedPreferences pref= PreferenceManager.getDefaultSharedPreferences(getActivity());
String text = pref.getString("example_list","");
int foo = Integer.parseInt(text);
goToPage(foo);
//some irrelevant code there
}
So the main task of the code is to get a value from my example_list preference (a string), turn it into an integer and put this integer into my goTopage();, which makes the app jump to a certain page in my pdf document.
The problem is this part:
PreferenceManager.getDefaultSharedPreferences(getActivity())
getActivity isn't working. I have tried getApplicationContext() aswell. What should be in the brackets of getDefaultSharedPreferences()?
getDefaultSharedPreferences expects an instance of Context class. getActivity method is declared in the Fragment class, so, unless your onLoadFinish method is declared in any Fragment successor, you can't use it. Per your comments, if I understood you correctly, onLoadFinish is declared inside Activity. If so, you can just use this keyword to pass the context, because Activity is a successor of Context. If this method is declared in another class, you should pass context to it, via constructor injection, for example.
EDIT Example of providing context via constructor injection.
Let's say you have the following interface:
public interface MyInterface {
void myAction();
}
And you have a class, which implements it and requires an instance of Context to do the work:
public class MyClass implements MyInterface {
private WeakReference<Context> mContext;
public MyClass(Context context) {
this.mContext = new WeakReference<Context>(context);
}
#Override
public void myAction() {
Context ctx = mContext.get();
if (ctx != null){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
//do stuff
}
}
}
As you can see, Context instance is injected via constructor and we don't keep a strong reference to the context (actually it depends on specific needs). This class can be used inside Activity in the following way:
MyClass myClass = new MyClass(this);
Or inside fragment:
MyClass myClass = new MyClass(getActivity());
PreferenceManager should be used with a PreferenceActivity.
Just use context.getSharedPreferences("pref_name", Context.MODE_PRIVATE);
getDefaultSharedPreferences required your application context a parameter,
Try this,
public class MyActivity extends ActionBarActivity
{
......
.......
PreferenceManager.getDefaultSharedPreferences(MyActivity.this);
......
......
}
I'm trying to use the array in my android program.
I did this
public class MainActivity extends Activity {
TextView[ ] answer = { new TextView(this) };
and, I tried to do use answer[0]
but it gives me errors. Is there any problems with me initializing the arrays?
(I want to create, and initialize them at once)
Guys thank you.. figured it out by help!
I did
TextView[] answer;
in Main
and did
TextView[] answer = {new TextView(this)};
in On create
this made me able to use answer in other methods! thank you guyz!
The statement
TextView[] answer = { new TextView(this) };
needs to be in an instance method such as onCreate. If you need to access it outside the method declare it as a class member variable:
public class MainActivity extends Activity {
private TextView[ ] answer;
#Override
public void onCreate(Bundle savedInstanceState) {
...
answer = new TextView[] { new TextView(this) };
}
....
}
It refers to the instance of MainActivity on which onCreate() has been called.
In general, from the Java Language Specification, 15.8.3:
The keyword this may be used only in the body of an instance method, instance initializer or constructor, or in the initializer of an instance variable of a class. If it appears anywhere else, a compile-time error occurs.
When used as a primary expression, the keyword this denotes a value that is a reference to the object for which the instance method was invoked (ยง15.12), or to the object being constructed. The type of this is the class C within which the keyword this occurs. At run time, the class of the actual object referred to may be the class C or any subclass of C.
You should try this.
public class MainActivity extends Activity
{
TextView[] answers;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
answers = new TextView[]{new TextView(this)};
}
}
It should be defined as:
TextView[] answer = new TextView[]{new TextView(this)};
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