Application crashes on call to a new activity - java

this might not be a new question to you - I have my main activity and I would like to call a method in another activity. Now if I do this I get my application not responding and closed.
I hear there is some special way to call methods in other activity classes?

This is generally a bad idea, the reason why is because you have no control of the life-cycle of an activity that is not the active Activity. You could call a method and find that the activity you are calling has been destroyed to reclaim resources.
A better option would be to create a Utility class that can provide functions to multiple activities, or place things that must remain throughout the life-cycle of your application into the application class, or shared preferences.
If all your trying to do is pass information to a new activity or get information from another one, you may want to package that information into the intent, or again place it in shared preferences.

Just create another class and place that method in that class.Then access from both activity.

Related

why cant we create an activity using new keyword?

why we have to launch an activity using intent
why cannot we launch it using Activity a = new Activity ??
i tried searching in android developers but did not get any answer
You can, but it won't be fully initialized. There's a series of functions on the Activity that needs to be called in the right order to correctly initialize it, and a series of steps taken by the framework in order to display the activity. Calling startActivity will take those steps and call the Activity lifecycle functions in the correct order. So there's no reason to use new.
Looking at it another way- lets say you were to do Activity a = new Activity(). How would the OS know you did that, and know its supposed to display that Activity? How would it know that the Activity is now supposed to go into the foreground? It wouldn't. It needs to be told that a new Activity was launched. That's why startAcctivity exists. And since you have to call that anyway, why not just make it a factory method as well, so initialization and launching are one step?
Not only you can create an activity object using the new keyword, but also you can inflate its layout/sub-views and then even launch it.
But the approach of implementing things above is very tedious and error-prone. And it is not recommended if you are dealing with normal Android app development.
If you are curious on how it is done, have a look at these github projects:
https://github.com/singwhatiwanna/dynamic-load-apk
https://github.com/didi/VirtualAPK
https://github.com/DroidPluginTeam/DroidPlugin
These projects aim to load and launch external Activities/Services from UNINSTALLED apk files. One tiny aspect of the way they implement this is by creating activities with new.

Why does intent requires context?

While working with different activities and starting them for results I have no choice but to use intent. Now intent requires context and that makes no sense to me. I know that context allows access to the application resources but
why do you need to know about the application resources when an intent is just a simple messenger?
Also, I am not so sure why some people create intent with the getApplicationContext() while other use this for the activity context????
Lastly, I am not so sure how the activity that calls for startActivityResult() receive a call back on the method onActivityResult() when I don't pass the "this" for the context but instead the application context. I thought that you have to use the "this" or passing in the current activity context that called startActivityResult() in order to receive a callback. That is just straight up java right? If you pass in a class then the other activity class will have a reference to your class and hence allows it to call the method in your class which is onActivityForResult(). However, this is not the case so what am I missing?
Intent itself does not need the Context. The constructor Intent#Intent(Context, Class) is just a convenience constructor, that internally uses the provided arguments to derive a ComponentName. ComponentName is in turn just a package name of your app and a class name to target. So ComponentName might be something like:
com.foo.bar/com.foo.bar.ui.activity.MyActivity
However, you can as well just use an empty constructor Intent#Intent() and provide ComponentName yourself (Intent#setComponentName(ComponentName)).
Therefore it doesn't matter if you provide your Application's or your Activity's context (the latter is just simpler to type). Also keep in mind that classes that require application context can call Context#getApplicationContext themselves, so this is not something you need to worry about.
About startActivityForResult() - Android manages internally a stack of your Activity records. Therefore it delivers the result to the previous Activity on the stack. It is the same way it knows where to return, when you click "back".
Please note it doesn't mean it maintains a stack of your Activity instances. These instances might be long gone - destroyed and garbage collected to free the memory. However the stack contains the information that allows to recreate them and to restore their state.
Intent does not need Context for itself but as you yourself pointed out that Intent is just a messenger. It also passes the current state of application/object to the newly created object so that it can understand that what exactly is going on in the application. And that is why we need to pass the context.
And, I believe that you want to ask about startActivityForResult(). Android itself takes care of the callback in the same way other callbacks are handled. You can take the example of Activity Life-cycle. Whenever it is started onCreate(), onStart(), onResume() are called itself by Android.
Not been much deep into Android development but still let me try with an explanation. So basically, context is a reference to linking your resources to your program. Each object is given its own context, which contains the resources required to set that object up. It is required for many objects to be created, and to get program identifying information, among other purposes. This makes it invaluable to set up new views and activities, but it can also be used for other purposes. See this Android Context for more information.
According to this page Activity inherits context. Thus, if you are in an activity, you only need to pass itself to use the context. It also contains a pointer to getBaseContext(). You might occasionally need to reference that, if you need the entire application context, but most likely you won't for a while.
There are ways of creating an Intent which do not require a Context. But if you want to target a specific class of a specific package, then providing a context for the target package is a ready way to do that. Refer this Context Lesson.
As explained by snctin in his answer getApplicationContext() offers application context. Basically the Application context is associated with the Application and will always be the same throughout the life cycle of your app. Also refer this post.
See Android - How to start (display) a new Activity. According to it
startActivity(new Intent(this, ProjectsActivity.class));
assumes your current class extends one of the Android Activity classes, which gives you access to the startActivity method.
According to Getting result from a activity, Starting another activity doesn't have to be one-way. You can also start another activity and receive a result back. To receive a result, call startActivityForResult() (instead of startActivity()).
For example, your app can start a camera app and receive the captured photo as a result. Or, you might start the People app in order for the user to select a contact and you'll receive the contact details as a result. This post will help you understand the same more better way.
Hope that helps. And also thanks becuase of your question I had a refresh with Android.:)

Android: ActivityCompat.requestPermissions requires activity and not context :/

I'm calling ActivityCompat.requestPermissions in order to get permissions under android M, however, this requires an activity in the argument. This would be fine, except that I want to call it from a singleton, and the singleton can be used by any activity in the app.
ActivityCompat.requestPermissions(context, PERMISSIONS_LOCATION, REQUEST_LOCATION);
I want to avoid holding a reference to any activity within the singleton as that's a surefire recipe for a memory leak, and also I'd prefer that the singleton not hold an activity at all because it requires useless code in all the activities that call (every single one of them is going to have to include an extra argument in the getInstance() in order for the singleton to hold an activity - the singleton needs to get the activity from somewhere).
Now, I can technically get an activity and then set it to null straight after I request the permission, however that still leaves me with tons of useless activity arguments in every single activity where I make a call to the singleton. Is there a more elegant solution to this problem that I'm just not seeing?
The documentation on requestPermissions says that the activity parameter is the target activity where you want to show the pop up if you haven't included the permission in your manifest and for this purpose that method requires you to pass an activity and not the context, because upon finish the request permissions task it will then return a result to the calling activity(that is the activity passed as the parameter to the method). If you are so adamant about implementing this through your singleton I suggest you create a function that accepts the activity in the parameter and the callbacks too as you WILL need to handle the callbacks if the permissions were given or not

Is it bad practice to pass the instance of an Activity as a parameter and finish() it from a different class?

I have a few Activities that use the exact same methods logout() and redirect() multiple times.
Would it be alright to use a separate class and mark these methods as static as follows:
public class AuthUtil {
public static void redirect(SessionManager manager, Activity activity) {
manager.redirect();
activity.finish();
}
public static void logout(SessionManager manager, Activity activity) {
manager.logoutUser();
activity.finish();
}
}
And call them from the activity by:
AuthUtil.logout(mSession,this);
Or should I be extending the Activities that use the method to a common Activity class and just put the methods there (except without the parameters since the methods wouldn't need them in that case)? However, I won't be able to do this if one of the activities extends FragmentActivity, another ActionBarActivity, which is actually the case for me...
Basically, I want to know if it's bad practice to call the activity's methods like that from a separate class body than its own? If so, what should I be doing?
No it is not considered bad practice - but choosing that route because it is easiest may well be a decision you later regret.
You should ask yourself the following questions:
Who is responsible for finishing the activity?.
Who knows when to finish the activity?.
Who knows how to finish the activity? (usually the Activity but be certain).
In your case it could be:
The activity itself
The session manager
The algorithm
Something else entirely
Once you have answered those questions you should have a good idea how to implement.
Remember that you could also create a third object, perhaps an ActivityManager that takes responsibility. It could hold a list of activities that need to be finished when the SessionManagercompletes the session. You may then have:
sessionManager.redirect(activityManager);
other scenarios could result in
// Make sure when the session completes this activity is finished.
sessionManager.registerAttachedActivity(Activity activity);
or
// Activity must finish when redirect completes.
activity.finish(sessionManager.redirect());
It really isn't as simple as good practice and bad practice it's more about doing it right.
Would it be alright to use a separate class and mark these methods as
static as follows
No. It would make very difficult to figure out where are the activities being finished by looking only at the source code of a given activity. And its also hard to see in what thread are those methods running for instance. And finally, because they are static, you'll have to add a new method if an activity needed to perform additional or different actions when redirecting or logging out.
Or should I be extending the Activities...
In my experience it is not a good idea to tie activities to an inheritance hierarchy, and you named a few good reasons for not doing so. If you need code reuse try to use composition instead.
I'd always call Activity.finish from the very same activity, in fact I'd like to have the whole lifecycle picture contained in the activity's code. But this is just what my guts tell me, there's no definitive correct answer to your question.

Changing a TextView in another class from a Service

I have two classes, one is a standard activity, the other a service. I would like the service to update a TextView (via .setText()) of the Activity on certain events that happen within the service.
I've tried to achieve this by programming something like a setter-method inside the Activity-Class, but TextViews don't accept a static-reference, and when I try invoking an instance of the Activity-class instead (via MyActivityClassName aVariable = new MyActivityClassName();), I get a NullPointer Exception, even though the View in questions is visible at the time of the call.
Could anyone tell me what I'm doing wrong :-)? It is probably more of a basic Java question than an Android-one, but since it might have to do with the nature of Android-services, I've still added the android-tag.
Thanks for your help!
I would like the service to update a
TextView (via .setText) of the
Activity on certain events that happen
within the service.
I would strongly recommend greater logical decoupling. Have the Service tell the Activity to update the TextView.
You can do that via a broadcast Intent, or by having the Activity provide a listener object that the Service calls. In either case, be sure the Activity detaches from the service (unregisters the listener or broadcast Intent receiver), lest you cause a memory leak.
And, of course, this only works if the activity is actually running.

Categories

Resources