I know I can use getApplicationContext() to get Context from sub class of ListActivity.
but PublicPar is common class, how can I get Context from this class.
public class SMSMain extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
Context my=getApplicationContext();
}
}
public class PublicPar {
public static void SetNotification(){
}
}
If you have a common (helper-type) class like your PublicPar class, the best you can do is to pass context as a parameter to each method:
public static void SetNotification(Context context) {
}
Remember to not set this context to any PublicPar class variable to avoid leaking it.
Try this. It should work:
public class SMSMain extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// Context my=getApplicationContext();
new PublicPar().SetNotification(SMSMain.this)
}
}
public class PublicPar {
public static void SetNotification(final Context context ){
// You can proceed with using the context here.
}
}
If you don't want to pass the Context around as part of constructor argument, you can expose a static method in the application.
public class MyApplication extends Application {
private static MyApplication myinstance;
public MyApplication() {
myinstance = this;
}
public static Context getAppContext() {
myinstance.getApplicationContext();
}
}
Related
I have an activity which instantiate a class with an interface. How I can get the android context within MyClass with only the reference to the interface?
public class TestActivity extends Activity implements MyInterface {
#Override
public void onCreate(final Bundle savedInstanceState) {
final MyClass myClass = new MyClass(this);
}
#Override
public void onChange() {
}
}
public interface MyInterface {
void onChange();
}
public class MyClass {
public MyClass(MyInterface myInterface) {
// how to get context from myInterface ???
}
}
public class MyClass {
public MyClass(MyInterface myInterface) {
// Get Context
Context context = null;
if (myInterface instanceOf Context)
context = (Context)myInterface;
}
}
If your Activity (which extends Context) is implementing MyInterface and you pass that to MyClass, you just need to cast it to the appropriate type.
The context is only available in Activity classes or global Context, if you have to use the context, change your code:
public class TestActivity extends Activity implements MyInterface {
#Override
public void onCreate(final Bundle savedInstanceState) {
final MyClass myClass = new MyClass(this);
}
#Override
public void onChange() {
}
}
public interface MyInterface {
void onChange();
}
public class MyClass {
public MyClass(TestActivity activity) {
//now, you can use the context of your activity or do a cast
// to your interface
MyInterface interface = (MyInterface) activity;
}
}
I think you approached it a bit wrong, but I might miss understood your design concept what you want to achieve.
Create your Interface in the Class where you want to obtain the Context from and the use implement like you did in your activity.
YourContextClass() {
private MyInterface interface;
onCreate() {
interface.onChange(this);
}
public interface MyInterface() {
void onChange(Context context);
}
}
Then in your Activity class implement MyInterface, and inside the method, you can obtain the Context.
YourActivity implements MyInterface {
private Context context;
...
void onChange(Context context) {
this.context = context;
}
}
But this is only necessary if you really need the context from Interface... otherwise, in you Activity, I see you are extendingActivity, which gives you access to the Context with getContext();
I tried to call the "AsyncTask" class from another class called "MainActivity" but "AsyncTask" Class is inside the class called "SiteAdapter". I tried to pass a reference but it not working. How could do that?
Main Activity:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("StackSites", "OnCreate()");
setContentView(R.layout.activity_main);
//Call the class AsyncTask
new GetAddressTask(this).execute(); // <----ERROR - GetAddressTask cannot be resolved to a type
}
}
AsyncTask inside SitesAdapter class:
public class SitesAdapter extends ArrayAdapter<StackSite> {
...//PROCESS
public class GetAddressTask extends AsyncTask<String, Void, String> {
Context mContext;
public GetAddressTask(Context context) {
super();
mContext = context;
}
//Pass a reference to MainActivity
private MainActivity mainActivity; // <--- WARNING - The value of the field SitesAdapter.GetAddressTask.mainActivity is not used
public GetAddressTask(MainActivity mainActivity)
{
this.mainActivity = mainActivity;
}
#Override
protected String doInBackground(String... arg0) {
...
}
#Override
protected void onPostExecute(String result) {
...
}
}
}
First of all, MainActivity is not a class that you can not define an object from. It extends Activity.
Change your AsyncTask class with it;
public static class GetAddressTask extends AsyncTask<String, Void, String> {
Context mContext;
public GetAddressTask(Context context) {
super();
mContext = context;
}
#Override
protected String doInBackground(String... values) {
// If you want to use 'values' string in here
String values = values[0];
}
#Override
protected void onPostExecute(String result) {
...
}
}
Then call this with it;
String values = ""; //You can pass any string value to GetAddressTask with that parameter
//Call the class AsyncTask
new SitesAdapter.GetAddressTask(this).execute(values);
make GetAddressTask static:
public static class GetAddressTask
Try this, this is working for me.
Just create a method in your SitesAdapter class and call it from your MainActivity like this :
new SitesAdapter().start(MainActivity.this);
now in your SitesAdapter class do this :
private Context mContext;
public void start(){
mContext = context;
new GetAddressTask().execute();
}
May this help you
You could make it static then call it with
SitesAdapter.GetAddressTask myClass = new SitesAdapter.GetAddressTask();
myClass.execute();
But, if you are going to be needing this in multiple activities, then it is probably worth it to take it out of that class and put it in its own file.
If you will need to update your UI from the task, you can see this answer on using an interface with a callback to your calling Activity.
I have an Activity and non Activity class. How to call a method in Activity class from non Activity class
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
DataClass dc = new DataClass();
dc.show();
}
public void call(ArrayList<String> arr) {
// Some code...
}
}
public class DataClass {
public void show(ArrayList<String> array) {
// Here I want to send this ArrayList values into the call
// method in activity class.
MainActivity act = new MainActivity();
act.call(array);
}
}
Just create a callback interface inside the DateClass.
public DateClass {
public interface IDateCallback {
void call(ArrayList<String> arr);
}
private IDateCallback callerActivity;
public DateClass(Activity activity) {
callerActivity = (IDateCallback)activity;
}
...
}
public void show(ArrayList<String> array) {
callerActivity.Call(array);
...
}
//And implements it inside your activity.
public class MainActivity extends Activity
implements IDateCallback {
public void call(ArrayList<String> arr) {
}
}
Well there are several things you could do. I think the easiest for you would be to send the Context into DataClass like so:
DataClass dc =new DataClass();
dc.show(this);
And in your DataClass save the context into a global var Context context. Then use it like so:
((MainActivity)context).call(array);
((MainActivity)getContext).array();
Just make a singleton like:
TeacherDashboardSingleton:
public class TeacherDashboardSingleton {
public Teacher_Dashboard aa;
private static final TeacherDashboardSingleton ourInstance = new TeacherDashboardSingleton();
public static TeacherDashboardSingleton getInstance() {
return ourInstance;
}
}
myActivity class:
onCreate(....){
....
TeacherDashboardSingleton.getInstance().aa = this;
....
}
this will create an object of same instance as in activity
now you can use it from anywhere
MyI don't understand why I get a compile error for this:
public class Main_screen extends ListActivity {
List<Object> completeList;
private My_ArrayAdapter adapter;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
completeList = getCompleteList();
adapter = new My_ArrayAdapter(this, completeList);
setListAdapter(adapter);
}
public void doSth() {
...
}
}
and in My_ArryAdapter:
public class My_ArrayAdapter extends ArrayAdapter<Object> {
private final List<Object> list;
private final Activity context;
public My_ArrayAdapter(Activity context, List<Object> list) {
this.context = context;
this.list = list;
}
public void tryIt() {
context.doSth(); // <-------- THIS DOES NOT WORK, this method can not be called
}
}
Please explain, is there something fundamental I have not understood. I am just passing the context into the ArrayAdapter instance I create. And from within this instance I would like to acccess the caller's method.
Why shoudl this not be possible?
Many thanks!
try this:
public void tryIt() {
((Main_screen)context).doSth();
}
context is Activity and it hasn't doSth(), but Main_screen has, so you should cast to this class
Actually you are making Activity context object and passing a child of Activity (i.e Main_Screen), Its called upward cast (Implicit Casting).
So the Activity (as parent) has no method of doSth(). So you need downward Casting (Explicit casting) to make it a Main_Screen.
Two ways to do this.
make an Object of Main_Screen context instead of Activity context
or
cast it as Main_Screen in tryIt() method to avail Main_Screen methods like this way:
if(context.isInstance(Main_Screen.class))
{
((Main_Screen)context).doSth()
}
you can also use try catch to minimize the chances of ClassCastException
You can use the below code. Obviously class context don't contain an object doSth(). doSth() is declared in class Main_screen.
public class My_ArrayAdapter extends ArrayAdapter<Object> {
private final List<Object> list;
private final Activity context;
public My_ArrayAdapter(Activity context, List<Object> list) {
this.context = context;
this.list = list;
}
public void tryIt() {
Main_screen.doSth();
}
}
How I did it
StaticCommonDataClass -> maintains static data here I will keep the instance of Activity one in it.
ActivityOneClass -> Contains the method that I have to access in ActivityTwo actually.
ActivityTwoClass => Will access the ActivityOne Method.
What I hate is to pass two many parameters from one function to other function or one class to other class,
that too when it has to be done for similar values again and again.
Here i will store refrence of ActivityOneClass in static Variable.
public class CommonStaticData {
private static Activity _activity;
private static Context _context;
public static void setactivity(Activity activity) {
_activity = activity;
}
public static Activity getactivity() {
return _activity;
}
public static void setcontext(Context context) {
_context = context;
}
public static Context getcontext() {
return _context;
}
}
public class ActivityOneClass extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity1);
CommonStaticData.setactivity(ActivityOneClass.this); //will keep the instance alive for this activity
}
Public void activityOneMethod()
{
//Set of statements
}
}
public class ActivityTwoClass extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity2);
((ActivityOneClass) CommonStaticData.getactivity()).activityOneMethod();
//we need to typecast the instance stored in CommonStaticData.getactivity() to "ActivityOneClass" thats is the
//activity containing the method so as to access the method otherwise it will not come in the intellisense window and will generate Compiler Error
}
}
MAIN ACTIVITY
public class MyActivity() extends Activity
{
onCreate()
{
MyClass myobj=new MyClass();
}
public void Mymethod()
{}
}
//HELPER CLASS IN A SEPARATE FILE
public class MyClass()
{
MyClass(Context context)
{
}
}
I tried to call Mymethod() from an instance of MyClass.
I would really appreciate any help. Thanks.
Why not just pass the activity to the constructor like
public class MyActivity extends Activity {
onCreate(){
MyClass myobj=new MyClass(MyActivity.this);
}
public void myMethod(){
}
}
//HELPER CLASS IN A SEPARATE FILE
public class MyClass{
public MyClass(MyActivity act) {
act.myMethod();
}
}
Make that method as static so you can call without creating the class object
public static void Mymethod()
{}
and call like this way
MainActivity.Mymethod();
This is probably the best way to do it. This is how I'm doing it. It's called a Singleton Design Pattern:
public class MyActivity extends Activity {
private static MainActivity instance;
public static MainActivity getInstance() {
if(instance==null){
setInstance(this);
}
return instance;
}
public static void setInstance(MainActivity instance) {
MainActivity.instance = instance;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setInstance(this);
}
}
If I'm understanding you correctly I believe you can solve your problems using an interface as a callback.
////ACTIVITY/////////////////////////////////
public class MyActivity() extends Activity {
onCreate()
{
MyClass myObj=new MyClass();
//Set the listener on the object. Created as anonymous
myObj.setListener(new MyClass.Listener() {
myMethod();
});
}
}
public void myMethod(){
}
//////Custom Class//////////////////
public class MyClass {
Listener mListener;
public interface Listener {
public void onInterestingEvent();
}
public void setListener(Listener listener) {
mListener = listener;
}
public void someUsefulThingTheClassDoes() {
//Do your code here and when you're ready to call the activity's method do this
mListener.onInterestingEvent();
}
}
I had an inner class that I wanted to pull out into a more general library "Helper" class. I had the same issue you do. I got around it by making the helper class abstract, with a single abstract method. Then in my project package I extended the helper class with a constructor call in the specific class.
public class MyActivity extends Activity {
onCreate() {
MyHelperClass = new MyHelperClass(this, "foobar");
}
public void myMethod() {
// Code...
}
}
// In a different file
public class MyHelperClass extends HelperClass {
private MyActivity mInstance;
public MyHelperClass(MyActivity act, String data) {
super();
this.mInstance = act;
this.mActivity = act; // Useful for calling generic Activity methods in the HelperClass
this.mData = data;
}
protected void callMyActivityMethod() {
mInstance.myMethod();
}
}
// In a different file
public abstract class HelperClass {
protected Activity mActivity;
protected String mData;
public HelperClass() {
// Subclass will set variables
}
protected abstract void callMyActivityMethod();
// More code for all the other stuff the class does
}
In this way, I have a helper class that contains the vast majority of the "work", and all I have to do is make a subclass with the constructor and one method in order to get access to the calling activity's method of interest.
You have to pass instance of MainActivity into another class, then you can call everything public (in MainActivity) from everywhere.
MainActivity.java
public class MainActivity extends AppCompatActivity {
// Instance of AnotherClass for future use
private AnotherClass anotherClass;
#Override
protected void onCreate(Bundle savedInstanceState) {
// Create new instance of AnotherClass and
// pass instance of MainActivity by "this"
anotherClass = new AnotherClass(this);
}
// Method you want to call from another class
public void myMethod(){
...
}
}
AnotherClass.java
public class AnotherClass {
// Main class instance
private MainActivity mainActivity;
// Constructor
public AnotherClass(MainActivity activity) {
// Save instance of main class for future use
mainActivity = activity;
// Call method in MainActivity
mainActivity.myMethod();
}
}
In MainActivity.class file
You have to pass MainActivity context from MainActivity Class. Then in MyClass you have to Get MainActivity context. Remember Context and MyActivity are two different reference.
public class MyActivity extends Activity
{
onCreate(){
MyClass myobj=new MyClass(MyActivity context);
}
public void Mymethod(){}
}
//HELPER CLASS IN A SEPARATE FILE
public class MyClass()
{
MyActivity context;
MyClass(MyActivity context)
{
this.context = context;
this.context.Mymethod();
//Or you can directly use activity context
context.Mymethod();
}
}
I decided to write the HelperClass MyClass as an inner class of MyActivity class. This allows it full access to parent class but the bad thing is now MyClass is restricted to MyActivity class only.
public class MyActivity() extends Activity
{
onCreate()
{
MyClass myobj=new MyClass();
}
public void myMethod()
{
}
}
//INNER CLASS
public class MyClass
{
public MyClass()
{
}
//I can directly access the MyMethod
myMethod();
}