invoke a method from activity in another - java

i know that this question was asked before but i had tried all the solution and get Error
i have two activity on android studio ...
the first called 'MainActivity' and contain a method ' deleteFromArrayList() '
the secound on called 'DeletButtonActivity' and contain a method ' delete(View v) '
i want to invoke 'deleteFromArrayList ()' wihtout creating another class or make the method static .... becouse i have an ArrayList inside deleteFromArrayList()
note : i send value of index i want to delete from array list using Intent ..the code in DeleteButtonActivity is
public void delete(View v) {
try {
Intent i = new Intent(DeleteButton.this, MainActivity.class);
i.putExtra("index", (int) spinner2.getSelectedItemId());
(new MainActivity()).DeletButtonActivity();
Toast.makeText(getApplicationContext(), "it was deleted", Toast.LENGTH_SHORT).show();
}
catch(Exception e){
Toast.makeText(getApplicationContext(), e+"", Toast.LENGTH_SHORT).show();
}
}
and the code in MainActivity
public void deleteFromArrayList (){
this.arrayList.remove(getIntent().getIntExtra("index",-1));
}
when i run the app i got an Error NullPointerException,,,
can anyone help me ..please
hope that i describe the problem very well

Activities in Android are no just a simple class but they also have a Lifecycle:
An activity has essentially four states:
If an activity is in the foreground of the screen (at the top of the
stack), it is active or running. If an activity has lost focus but is
still visible (that is, a new non-full-sized or transparent activity
has focus on top of your activity), it is paused.
A paused activity is
completely alive (it maintains all state and member information and
remains attached to the window manager), but can be killed by the
system in extreme low memory situations.
If an activity is completely
obscured by another activity, it is stopped. It still retains all
state and member information, however, it is no longer visible to the
user so its window is hidden and it will often be killed by the system
when memory is needed elsewhere.
If an activity is paused or stopped,
the system can drop the activity from memory by either asking it to
finish, or simply killing its process. When it is displayed again to
the user, it must be completely restarted and restored to its previous
state.
So the problem with your code is that when you want to access the array in a stopped activity, the instance you have been using before might not be alive anymore.
How to solve your problem
A very simple approach is to use parameter passing before you do the transition from one activity to the other, for this you'd pass your Array as an intent extra and then you "get the result back" when you finish the second activity by using onActivityResult() callback.
A second approach could be to use a Service that is something similar to an Activity but it has no UI and it has its own lifecycle. Being able to be alive even when you app it is not. Using a Service, you'll keep the Array inside the service and you'll communicate with the array to do the usual operations.
A third approach could be to use an EventBus. A very simple communication mechanism between Activities, Fragments, Threads, Services. There's a great talk titled Android Application Architecture on Android Dev Summit 2015 that uses EventBus as a communication mechanism and to implement a MVC architecture pattern on a REST Android App.
Back to your question. If you just need to 'share' an array between two activities, use the first approach. The second and third are just examples of different alternatives for the case you need a lot more than that.

You must not do this. There are mechanism to communicate between activities or fragments.
On can be, using startActivityForResult, this is Activity A calls Activity B, then in B you do something, and communicate the result back to Activity A.
You can have another workaround to what you want. If you can access the data in both of your activities, you can modified in ether one of them, when the activity starts, it will show the updated data.
Please first read well about an Activity here, and also provides more context of your question.

Related

Dealing with a service after the app was swiped and relaunched

I am working on an audio player app. The user may play the files, and a service is launched to allow them to play them in the background. I allow my service to continue playing the tracks even after the user chooses to swipe the app from the recent list.
Now, if the user swipes the app, the service will continue playing without issues but if the user opens the app using the notification associated with the service, I do not know how to handle this. To my surprise, the app actually continues working with the code above with no issues (as far as I can see).
Is there something I need to do to handle the said case? Do I need a way to reassign the service to the newly launched instance of my app?
Thanks.
Looks like you are already doing it. onStart() you check if the intent is null and if it is, you create a new intent and bind it to a service (if it exists) otherwise create a new service.
Since onStart() is called every time your activity (not application) comes back from background to the foreground (say you launched the setting page and then come back to the main activity), it seems excessive to bind service during onStart(). I would move binding inside onCreate() since onCreate() is only called once for an activity.
Checking for null intent seems weird and maybe redundant, if you move binding inside onCreate(), you can be sure that you are only binding when the activity is launched, and if service already exists, activity will just bind to it.

Dedicated Android Activity to initialize data and libraries for the application

My app makes use of various heavy libraries and data files, that need to be loaded / synchronized with local storage on start-up. As this operation takes some time, I was thinking of creating a dedicated activity for this purpose. This activity would be the entry point of the application and would do the following:
Display a background image and progress bar
Process necessary data (and updating the progress bar accordingly)
On completion, launch a new activity
Here is a couple of questions:
My initialization activity needs to pass a reference to the data to its child activity. Ordinarily I would do this with setSerializable, but here I am using 3rd-party non-serializable classes.
So I was thinking of simply making the data static. Is this a good solution? Any chance the static reference might break when switching activities or during the application life-cycle?
public class LibraryInitializer {
private static Some3rdPartyClass myLib;
public static void initialize(){ // Called by initialization activity
myLib = Some3rdPartyClass.create();
}
public static Some3rdPartyClass getMyLib(){ // Called by child activity
return myLib;
}
}
I need the initialization activity to be called only once. How to prevent that it is shown again when a user clicks on the back button?
More generally, is this approach okay, or would you suggest a better one? (I also considered using one single activity, but adding/removing the progress-bar and background dynamically)
Long running code really ought to be done using Android services. I would recommend doing your complicated logic in a service that your various "Activity" classes (which correspond to the views of your application) simply consume. Services can outlive the UI of the application and can also be started / initialized in response to various other events (like system boot), even when the user is not interacting with the application whereas an Activity is very tightly intertwined with the presentation.
In terms of loading / syncing data, I would strongly recommend against putting this logic in your activity code... instead, use a SyncAdapter or one of the other scheduling mechanisms for syncing. This will ensure that syncing activity is batched with other uses of the networking chip, which minimizes overall battery usage, and also allows you to have synced before the user is actively using your application, so that you aren't keeping the user waiting when they open your app.
When you start a new Activity from the loading Activity call the finish() method to close that activity and it will be deleted from the applications activity stack. like below:
startActivity(intent);
finish();
For the question for passing data through activities, extend the Android Application class, where you can define the global state and variables of your application.

How disable destroy my activity

My app contains Activity. I start it by Intent. Than I turn my Activity to background (switch to Home Screen or similar). After some time the OS destroy my Activity (I think when memory is low). It is possible protect my Activity (in background) from destroy by OS? Or increase it priority to maximum?
Activity is made for a UI holding elements. Service is made for background tasks. From this already sounds logic to make a Service instead of try to keep Activity in background.
Also there are BroadcastReceivers, which will be called on different actions. Boot completed, Internet lost, got and so on.
I think you know what do you want to archive, I would suggest telling in detail an will get a lot better response, with enumeration, maybe code part of component needed to use.
Keeping Activity forced alive is a bad idea in general.
You can load WebView in background.

How do you get an android app to launch multiple apps and then return to the initial app?

I am writing my first android app so I will try my best to be clear and precise. I can see some similar questions to this but none that seems to answer it exactly so perhaps it can't be done but here goes:
I have got my main activity to the point where it has data stored which includes a list of apps on the device that the user has selected to launch. On clicking a button on the main activity screen I would like the device to launch each of these selected apps in turn and then (ideally) return the user to the main activity that I have written. I would also like to define some restrictions on running each app - for example, each app runs for 30 seconds or until the app stops using the internet whichever comes earliest.
I don't believe I have any issue with linking all of this to the button click, nor is there any issue cycling through all of the selected apps. What I really need is the code to launch each app and then recall from it/move to the next app (ideally after the 30 seconds or when the app stops using the internet). Hopefully the below code makes clear where I am looking for help with the TODO. Does anyone know whether this is possible and if it is how can I get it done?
public class MainActivity extends Activity {
... //some code up here
//when the Run Apps button is clicked the onClick will run all of the selected apps using this Method:
public void RunApps(View view) {
//run through the list of Apps and run the ones that are selected
for (App application : list) {
if (application.isSelected()) {
/* TODO code that is meant to run the selected app and return to the main
* activity after say 30 seconds or when the app is done using the internet.
* As a starter I have the below but this is crashing and even if it did run
* I believe that it would not return me to the original main activity:
*/
Intent i = new Intent(Intent.ACTION_MAIN);
PackageManager manager = getPackageManager();
i = manager.getLaunchIntentForPackage(application.getPackageName());
i.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(i);
}
}
};
...//some more code here
}
just a couple of notes - the App class is defined elsewhere and includes the package name and whether the app has been selected by the user. list is a List of Apps.
I believe that the ACTION_MAIN and CATEGORY_LAUNCHER values may not be the best to use and perhaps startActivity(i) is not the right method for what I want but am not sure how that needs to be changed or whether there a more fundamental changes needed.
Many thanks for any help.
You should run each app from your top-level MainActivity sequentially by invoking them one-at-a-time.
Here's how:
Keep a counter in your MainActivity to indicate which app you are
currently invoking.
Use startActivityForResult() instead of startActivity() to start
your applications. This will cause execution to return to
MainActivity.onActivityResult() when each of the apps is finished.
The requestCode of startActivityForResult() will be returned to
onActivityResult(), so you will know which application completed.
Therefore, MainActivity can increment the counter and start the
next application in onActivityResult().
Restriction:
One of your requirements is to return to MainActivity after each
app completes. These steps satisfy that requirement.
Another requirement is to return to `MainActivity after all of the
apps are finished. These steps also satisfy that requirement.
You will know when you have finished
the final app because of the value of your counter.
The final requirement is to limit the duration of each app to 30
seconds. This is a more difficult problem. You will use a Timer in
your MainActivity as a watchdog to monitor the spawned apps. Use methods
described here to stop the spawned app when time runs out:
Finish an activity from another activity.
Warning: get everything else working first, before you try to externally stop an app.
That's all. Good luck!

Android App/Activity To Start Fresh Completely every time it starts or resumes?

I have a kid's app for Android and there are some unique considerations for this application since the app has basically no navigation (it's for young kids). I do not want to break my app UI (which has been successful on iPhone) by adding a quit/restart button.
What I really need is fairly simple -- I want my activity/app to start clean and new every single time it starts. Whether it's an initial load or whatever -- basically any time onResume is called I want a completely fresh instance of my app.
I initially thought I could just exit/quit/finish the app when the user leaves. But I haven't found a way to do this that doesn't cause crashes on start. Also every thread/stack overflow post about that idea is filled with people wagging their fingers and saying you should never ever quit an app on android.
If I can't quit the app onExit, is there something I can do to restart my activity every time onResume is called? (or would that be an infinite loop?).
Would greatly appreciate any help!
Try starting your main activity in onResume, and clearing the activity stack:
public void onResume() {
super.onResume();
startActivity(new Intent(this, MainScreen.class).addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
}
maybe these aren't the correctl flags to add, but check out the other Intent flags and this could do what you want!
intent flags documentation
Ended up getting it to work fine by calling finish() in onPause().
Again, I appreciate the advice from people saying "this is not how Android does things". I've got a pretty good understanding of the best practices at this point. This is an unusual situation for an unusual type of user.
in your reload you can try this..
onStop();
onCreate(getIntent().getExtras());

Categories

Resources