I just ran into this problem while coding android. If I have a non-static method (It has to be non-static for the code inside to work) in my main class, how am i supposed to call it from within another class, because obviously I can't create another instance of my main class without starting a new instance of the program?
public class MainActivity extends FragmentActivity {
public static String starttime = "";
public static String startdate = "";
public static String endtime = "";
public static String enddate = "";
public static boolean start = false;
}
public void setDateText() {
EditText TextStart = (EditText)findViewById(R.id.txt_start);
TextStart.setText(startdate + " at " + starttime, TextView.BufferType.NORMAL);
EditText TextEnd = (EditText)findViewById(R.id.txt_end);
TextEnd.setText(enddate + " at " + endtime, TextView.BufferType.NORMAL);
}
Any help on how to call the setDateText() method from another class?
Thanks in advance
Normally you can't call a non static method from a static type, so you would do:
MainActivity m = new MainActivity(); // No constructor needed in class def.
m.setDateText();
But, when the program starts, you're not giving your JVM anything to call at the start, so you need to add:
#Override
//the function called when activity is created
public void onCreate(Bundle savedInstanceState) {
//call the create fct. Of the base class
super.onCreate(savedInstanceState);
//load the layout specified in the layout.xml
setContentView(R.layout.main);
MainActivity m = new MainActivity();
m.setDateText();
}
This will be called when the activity is created.
Go to Android - A beginner's guide for more information.
Also watch your syntax, your method def is outside of your class def.
Without knowing which other class is trying to access the MainActivity instance, you will need to pass a reference of this instance to your other objects, probably by passing this into a constructor or method.
For example
public class MainActivity extends FragmentActivity {
public void someMethod() {
SomeClass someClass = new SomeClass(this); // pass this for callbacks
// ~ more
}
}
where SomeClass is a class where you need to call the MainActivity's setDateText method.
I am trying to understand the need for you to call the function from another activity. Your main activity is anyway not on the foreground, so if you call this function from there, date will not be shown. Once you finish the 2nd activity and you will be back to MainActivity, then only you need this function to be called.
If that is so, then you can use startActivityForResult() to start 2nd activity, and then pass the date information back to MainActivity through onActivityResult(). You can call this function in MainActivity itself.
If you have to invoke setDate() at the activity's launch, you can pass the date in the Intent when you launch the activity and pull the date in MainActivity's onCreate method.
If you have to invoke setDate() at a different time other than launch, you can send a broadcast from other activity/component and make MainActivity listen to the Broadcast and pull the date from the intent's data.
Related
I have a method name checkForUpdate() in UpdateActivity.java. It looks like this:
#NonNull
#SuppressWarnings("deprecation")
protected String checkForUpdate(int curVersionCode) {
HttpClient httpclient = new DefaultHttpClient();
...
}
I am trying to call it from anotherActivity. So I'm trying to use code like this:
private void callFromAnotherActivity() {
UpdateActivity updateApp = new UpdateActivity();
String result = updateApp.checkForUpdate(...);
}
so when I type updateApp. then a list of the methods of UpdateActivity.java appears but there is no checkForUpdate() method. Why?
so when I type updateApp. then a list of the methods of UpdateActivity.java appears but there is no checkForUpdate() method. Why?
This is because your method is not public and probably you haven't import the UpdateActivity.
Please be noted that you can't create an Activity by calling the following:
UpdateActivity updateApp = new UpdateActivity();
You need to use something like this:
// context is your activity context.
Intent updateApp = new Intent(context, UpdateActivity.class);
context.startActivity(updateApp);
My suggestion:
You need to move the checkForUpdate method from UpdateActivity and make it as an util. So, other activity using the method won't be dependent and coupled with UpdateActivity. Localize the method to an utility class something like this:
public class UpdateUtil {
...
#NonNull
#SuppressWarnings("deprecation")
public static String checkForUpdate(int curVersionCode) {
HttpClient httpclient = new DefaultHttpClient();
...
}
}
and then use the method with:
UpdateUtil.checkForUpdate(1);
If you can't move the code (e.g, you don't have ownership of the code), you can do these things:
Make the checkForUpdate as static method
Use EventBus to tell the UpdateActivity to do the update.
You should not create an instance of the activity class. It is wrong. Activity has ui and lifecycle and activity is started by startActivity(intent)
Check here : call a method in another Activity
I need some pointers on doing the following:
lets say i have 10/20 (number doesn't matter) of activities.
each of these activities has a textview that should work like a counter.
each of these activities has a button to go to the next activity.
this counter starts when the app is launched, and increment itself every second.
So what i did so far is:
have in my main activity a method that instantiate a class that extends Thread.
In that class in the run() method, i increment a variable when a second passes.
Now i'm stuck on what i should do next. Any pointers would be appreciated thanks.
Edit: i need a way to communicate from inside the run method, to whichever activity is now currently on screen, to update its textview.
Just a bit of theory here for standard Object Oriented Programming : stick to the recommended principles like Loose Coupling which makes your project code less tied to each other. You can read more on that later.
Now, using Events, you can setup a system that is synonymous with the natural Publisher/Subscriber design pattern. Like this:
The activity that needs to notify the other activities is called Publisher and the other activities that need to be notified are called Subscribers.
From here:
There are already built and tested libraries to do Events in android. Like my favorite EventBus.
Step 1 Add this line to your app-level build.gradle file:
compile 'org.greenrobot:eventbus:3.0.0'
Then create a simple Plain Old Java Object aka POJO class like this:
public class UpdateTextViewEvent{
private String textToShow;
public UpdateTextViewEvent(String text){
this.textToShow = text;
}
//add your public getters and setters here
}
Step 2 Notify others:
When you want to notify anyone of the changes, you simply called this method:
EventBus.getDefault().post(new UpdateTextViewEvent("Some new Text"));
Step 3 Receive notifications
For those who want to be notified of this event, simply do this:
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
NOTE: to actually handle the event:
#Subscribe
public void onEvent(UpdateTextViewEvent event){
String text = event.getTextToShow();
//now you can show by setting accordingly on the TextView;
}
This is so much easier to do, do decouple your code by eliminating static references in your different activities
I hope this helps! Good luck!
make that Textview in second class as
public static Textview text;
and call it in main activity as
SecondActivity obj=new SecondActivity();
obj.text.settext("");
You can create one another activity e.g. BaseActivity extend with Activity class and your all 10/20 activity extends with created BaseActivity Class.
You can use your textview with protected access specifiers.
What you need to do is inside the counter class, create an a method and passed in a TextView as the parameter. Then create an int variable and set the counter as the instance:
Like this
public static class Counter extends Thread{
private static int x;
#Override
public void run(){
x = counter;
}
public void setCounter(TextView tv){
tv.setText(String.valueOf(x));
}
}
Now call this method setCounter(TextView) in all the activity's onCreate() method you'll like to display the counter, and passed in your the layout TextView as the argument. Like this
...
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState):
....
TextView cTextView = (TextView)findViewById(R.id.texT1);
Counter c = new Counter();
c.setCounter(cTextView);
}
public boolean getFavourite(Winkel winkel){
boolean isFavourite = false;
MyDBHandler dbHandler = new MyDBHandler(context,null,null,1);
User user = dbHandler.loggedIn(); //This method isn't usable anymore
isFavourite = dbHandler.isFavourite(user,winkel);
return isFavourite;
}
I want to change this code to:
public boolean getFavourite(Winkel winkel){
boolean isFavourite = false;
MyDBHandler dbHandler = new MyDBHandler(context,null,null,1);
isFavourite = dbHandler.isFavourite(user,winkel);
return isFavourite;
}
I was using my database to keep track of which user was logged in at first, but it was really easy to change this by simply sending the data from my first activity to my second.
#Override
public void login(User user){
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("Username",user.getUserName());
startActivity(intent);
}
Then, in my second activity, I could call all the database functions by using this:
user.setUserName(intent.getStringExtra("Username"));
(Because I need the username as a key for my database.
However, my activity has three fragments, two of which use my adaptor for a recyclerview. These fragments implement the interface that is provided in my adaptor class, which is this one (just showing this to be complete, what the interface is is irrelevant, fact is that my fragments have to implement this interface).
public interface ItemCLickCallback {
void onItemClick(int p);
void onSecItemClick(int p);
}
Now, I need the username in my adaptor class. It has to come from my activity (because thats where its stored), and I can't use an interface because I'm already using one and I would have to override the methods in every fragment.
I could pass the data from my activity to all the fragments using a Bundle, then pass that along to the adaptor when creating it in my fragments. But that seems like a lot of excessive code. Any simpler way to do this? Thank you
EDIT:
In Adaptor class:
private CheckFavourite checkFavourite;
public void setCheckFavourite(final CheckFavourite checkFavourite){
this.checkFavourite = checkFavourite;
}
boolean isFavourite = checkFavourite.getFavourite(winkel);
public interface CheckFavourite{
boolean getFavourite(Winkel winkel);
}
Fragment:
public class Overview extends Fragment implements Adaptor.ItemCLickCallback
Activity:
public class SecondActivity extends AppCompatActivity implements Adaptor.CheckFavourite
Activity has to implement the seconde interface, fragment implements the second. But both of them are on the same adaptor instance.
What I need to do (in my activity basically):
adaptor.setCheckFavourite(this);
But I can't because I don't have the adaptor there, it gets created in my fragment.
I tried:
adaptor.setCheckFavourite(this.getActivity());
in my fragment, but that gives me an an error:
Error:(60, 51) error: incompatible types: FragmentActivity cannot be converted to CheckFavourite.
However
adaptor.setItemCLickCallback(this);
is working perfectly fine in my fragment (the other interface). How do I fix this?
:) You can use multiple inheritance. To be able to make a class implement multiple interfaces we need can have something like this:
public class MyClass extends MyOtherClass implements MyInterface1, MyInterface2, ... , MyInterfaceN {
// Need to implement all interface methods here
}
Hey I am pretty new to making android apps and I understand that the easiest way to pass data between two activities is through an intent.
In one of my classes (EventOptions.java), I call this line of code:
Intent i = new Intent(EventOptions.this, PhotoFetcher.class);
i.putExtra("imageArray", imageIDs);
startActivity(i);
imageIDs is a string array
In my PhotoFetcher class, I want to set a string array called imageIDs to the imageIDs string array that I am passing through the intent.
I want to set images as a global variable in my class:
public class MainActivity extends Activity implements View.OnClickListener{
Intent it = getIntent();
String[] imageIDs = it.getStringArrayExtra("imageArray");
...
}
This crashes my app however. Is this not allowed? And if so, how can I fix it? Thanks in advance!
Need to call getIntent() in a method instead of at class level. call it inside onCreate :
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// get Intent here
Intent it = getIntent();
String[] imageIDs = it.getStringArrayExtra("imageArray");
}
if I want to use the imageIDs array in another public class defined
in my PhotoFetcher class, do I need to call it again?
To get imageIDsin PhotoFetcher class either declare String[] imageIDs as global variable or pass imageIDs using PhotoFetcher class constructor
You have to use putStringArrayListExtra. You can convert your String[] to an ArrayList first.
Like so
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(imageIDs));
Intent i = new Intent(EventOptions.this, PhotoFetcher.class);
i.putStringArrayListExtra("imageArray", arrayList);
startActivity(i);
And then you can fetch it like you do, preferably in onCreate or after that call.
Intent it = getIntent();
ArrayList<String> imageIDs = it.getStringArrayListExtra("imageArray");
Share data without persisting to disk
It is possible to share data between activities by saving it in memory given that, in most cases, both activities run in the same process.
Note: sometimes, when the user leaves your activity (without quitting it), Android may decide to kill your application. In such scenario, I have experienced cases in which android attempts to launch the last activity using the intent provided before the app was killed. In this cases, data stored in a singleton (either yours or Application) will be gone and bad things could happen. To avoid such cases, you either persist objects to disk or check data before using it to make sure its valid.
Use a singleton class
Have a class to whole the data:
public class DataHolder {
private String data;
public String getData() {return data;}
public void setData(String data) {this.data = data;}
private static final DataHolder holder = new DataHolder();
public static DataHolder getInstance() {return holder;}
}
From the launched activity:
String data = DataHolder.getInstance().getData();
Use application singleton (I would recommend this)
The application singleton is an instance of android.app.Application which is created when the app is launched. You can provide a custom one by extending Application:
import android.app.Application;
public class MyApplication extends Application {
private String data;
public String getData() {return data;}
public void setData(String data) {this.data = data;}
}
Before launching the activity:
MyApplication app = (MyApplication) getApplicationContext();
app.setData(someData);
Then, from the launched activity:
MyApplication app = (MyApplication) getApplicationContext();
String data = app.getData();
ρяσѕρєя K hit the nail on the head, you're running a method where constructors and fields go. To make the variables (the imageIDs) global, it's quite simple and there are a few ways of doing it. Declare them outside any method, and then assign them in your onCreate or onResume (which will always be called).
Try this:
public class MainActivity extends Activity implements View.OnClickListener {
//global variable
String[] imageIDs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get Intent here
Intent it = getIntent();
imageIDs = it.getStringArrayExtra("imageArray");
}
}
When considering the case with android activity, the first method to work is its onCreate method..right?
Suppose i want to pass 2 parameters to android activity class say UserHome . For that am creating the constructor of activity class UserHome and accepting the params.
But when we are calling an activity we are not initializing the Activity class, we are just creating an intent of UserHome class.
Then how can we pass params to that activity from another activity without using intent.putExtra("keyName", "somevalue"); usage.
Experts please clarify how we can cover a situation like this.?
Not sure why you would not want to use the intent params. That is what they are there for. If you need to pass the same parameters from different places in your application, you could consider using a static constructor that builds your intent request for you.
For example:
/**
* Sample activity for passing parameters through a static constructor
* #author Chase Colburn
*/
public class ParameterizedActivity extends Activity {
private static final String INTENT_KEY_PARAM_A = "ParamA";
private static final String INTENT_KEY_PARAM_B = "ParamB";
/**
* Static constructor for starting an activity with supplied parameters
* #param context
* #param paramA
* #param paramB
*/
public static void startActivity(Context context, String paramA, String paramB) {
// Build extras with passed in parameters
Bundle extras = new Bundle();
extras.putString(INTENT_KEY_PARAM_A, paramA);
extras.putString(INTENT_KEY_PARAM_B, paramB);
// Create and start intent for this activity
Intent intent = new Intent(context, ParameterizedActivity.class);
intent.putExtras(extras);
context.startActivity(intent);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Extract parameters
Bundle extras = getIntent().getExtras();
String paramA = extras.getString(INTENT_KEY_PARAM_A);
String paramB = extras.getString(INTENT_KEY_PARAM_B);
// Proceed as normal...
}
}
You can then launch your activity by calling:
ParameterizedActivity.startActivity(this, "First Parameter", "Second Parameter");
I can see one situation where you'd be unable to use the standard method of passing the parameters via the Intent: When you're creating an activity that will be launched by another app (say, the edit activity of a Tasker plugin) and, therefore, do not have control over the Intent that will launch your activity.
It's possible to create an Activity that accepts parameters in its constructor. The trick to using it, though, is not to use it directly, but to use a derived class with a default constructor that calls super() with the appropriate arguments, as such:
class BaseActivity extends Activity
{
public BaseActivity(String param1, int param2)
{
// Do something with param1 and param2.
}
// Many more lines of awesomeness.
}
class DerivedActivity extends BaseActivity
{
public DerivedActivity()
{
super("param1", 42);
}
}
Naturally, if you need to generate the parameters to pass to BaseActivity(), you can simply replace the hard-coded values with function calls.
We can pass the value from parent activity to child activity using the bundled collection and shared preference.
1. Shared Preference
2. Bundle Collection
Passing data or parameter to another Activity Android
But you also can create very well a constructor of UserHome.
public class MainActivity extends Activity {
UserHome userHome = new UserHome(param1,param2);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
userHome.yourMethod();
}}
Why do you think that is not possible to initialize a contructor?..MainActivity is a class like any other, just that extends Activity, but also keeps the properties of a class, so that can have, constructors, methods, members.