I would like to call a method in an activity and pass an argument to it from a non activity regular class in android.
As i understand, i cant simple use the following code, plus it does not work:
int mySound = 0;
SoundsActivity soundsActivity = new SoundsActivity();
soundsActivity.playSound(mySound);
That code is located in a regular class called "MyAdapter".
There are a few ways you can do this. I can't be specific since you didn't really show any code.
You can't do what you're trying to do though. Activities can't be instantiated like that (as well as anything extending Context), and it won't do what you want.
Use a broadcast.
This will require that you have a Context object passed into your Adapter, which you can do simply by modifying the constructor and adding a global variable:
private Context context;
public MyAdapter(Context context) {
this.context = context;
}
Then you can use that Context to send a local broadcast with your own action:
Intent intent = new Intent("my_custom_action");
intent.putExtra("sound_type", 0);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
And receive that action in your Activity to call your method: See Context-registered Receivers
When you construct the Adapter, pass a Context object into it. If you're constructing from an Activity (hopefully SoundsActivity), use this:
MyAdapter adapter = new MyAdapter(this);
Use a callback.
Delcare an interface somewhere:
public interface AdapterCallback {
void onRequestPlaySound(int type);
}
Implement that interface in your Activity:
public class SoundsActivity extends Activity implements AdapterCallback {
//...
#Override
public void onRequestPlaySound(int type) {
playSound(type);
}
//...
}
Add the interface as a parameter in your Adapter's constructor:
private AdapterCallback callback;
public MyAdapter(AdapterCallback callback) {
this.callback = callback;
}
And then use callback.onRequestPlaySound(0); from wherever you need.
When you construct the Adapter, pass your SoundsActivity instance into it. This will only work if you're constructing the Adapter from SoundsActivity:
MyAdapter adapter = new MyAdapter(this);
Pass SoundsActivity directly.
This isn't the cleanest way, nor is it the recommended way, but it will work. In your Adapter:
private SoundsActivity activity;
public MyAdapter(SoundsActivity activity) {
this.activity = activity;
}
And from SoundsActivity:
MyAdapter adapter = new MyAdapter(this);
Then just call activity.playSound(0); where you need to.
I want to access a list from another class then put it inside my RecyclerViewAdapter object .
The first class which contains the list.
public class Class1 {
// The List :
List<Model1> mlisto = new ArrayList<>();
mlisto.add(new Model1("HOLA","Dep17",R.drawable.img));
mlisto.add(new Model1("bonjour","Dep17",R.drawable.img));
mlisto.add(new Model1("hi","Dep17",R.drawable.img));
}
The second class which access the list from the first class.
public class Class2 {
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this,new Class1().mlisto);
}
When I use new Class1().mlisto it returns nothing like an empty list
and the RecyclerView doesn't show anything on the app.
you can use interfaces
create an interface inside class1 like this:
public interface CustomListListener{
void onListChanged(List<Model1> myList);
}
create a property of listener inside Class1:
CustomListListener mListener;
add a public function for initializing the listener inside Class1:
public static void setOnListChangeListener(CustomListListener listener){
this.mListener = listener;
}
implement the listener inside Class2:
public class Class2 implements Class1.CustomListListener {
}
when you implement listener inside Class2, you will get a function inside class2 like this :
#Override
public void onListChanged(List<Model1> myList) {
// in here you will access the list that you created or changed inside class1
}
when you wanna send the myList data to class2:
1- initiate the mListener property :
for example you can initiate the mListener inside OnCreate Function of class
Class1.setOnListChangeListener(this)
this refers to class2 context
2- send the data to class2
inside your class1, whenever you want to update the list use mListener property like this :
mListener.onListChanged(myList);
this like you can change the list whenever you want and get the updated value inside onListChanged function, also you can add more functions inside your CustomListListener for different scenarios like removing items, adding items and etc...
You can access the list like this :
public class Class1{
private List<Model> mList;
public List<Model1> getList(){
mList = new ArrayList<>();
mList.add(new Model1("HOLA","Dep17",R.drawable.img));
mList.add(new Model1("bonjour","Dep17",R.drawable.img));
mList.add(new Model1("hi","Dep17",R.drawable.img));
return mList
}
}
And in second class, you can use it like this:-
RecyclerViewAdapterrr adapter = new RecyclerViewAdapterrr(this,new Class1().getList());
setAdapter() is important
your_recyclerview_object.setAdapter(adapter);
You can use sharedPreference to store the list and can access it anywhere in your project by using its key. The best approach is shared in this link TinyDb Example
I need to start AsyncTask in UI thread, but the Constructor has (MainActivity parentActivity)
parametr. I don't really understand why it should be implemented and how I must pass it.
Here Eclipse says "Cant resolve MainActivity to a variable." Same for Activity.MainActivity.
new DownloaderTask(MainActivity).execute();`
And the constructor.
public DownloaderTask(MainActivity parentActivity) {
super();
mParentActivity = parentActivity;
mApplicationContext = parentActivity.getApplicationContext();
}
Change this line...
new DownloaderTask(MainActivity).execute();
to this...
new DownloaderTask(MainActivity.this).execute();
And you are passing Context of MainActivity not the activity...so in DownloaderTask() constructor, the parameter will be Context type not MainActivity...The constructor should look like as below...
public DownloaderTask(Context context) {
super();
mApplicationContext = context;
}
you can call like following if you are calling directly from the MainActivity
new DownloaderTask(this).execute();
or if you are callling from an inner class you can call like
new DownloaderTask(MainActivity.this).execute();
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.
hi i am Using ArrayAdapter in ListView with custom Class object,HERE IS MY CODE
private static class NewsDetailAdapter extends ArrayAdapter<clsNewsItem>
{
private final Activity context;
List<clsNewsItem> newsList = null;
public NewsDetailAdapter(Activity context, ArrayList<clsNewsItem> clsNewsObjects) {
super(context, R.layout.listview_cell, clsNewsObjects);
this.context = context;
this.newsList = clsNewsObjects;
}
public void clear()
{
newsList.clear();
}
while i am working with this code AdapterObj.NotifyDatasetchanged() not working Due to i have not implemented addAll() method for this class,i cant understand how to write this Method so how can i Write Add All method for this ArrayAdaper class..can Any one help me please
Do you have specific need for subclassing? If you need to have some logic better have one ArrayAdapter as member instance and proxy its methods. Because the original ArrayAdapter already has all these methods readily available