this is my basic Sketch from the App I wrote, my Problem is that I Navigate between my Activities with (black arrows)
Intent intent = new Intent(this, someclass.class);
intent.putExtra("pos", pos);
startActivity(intent);
I am not using finish() to go back since I dont know wether it recreates my previous Activity, or if it just goes back without recreating. The main Problem here is that i need to pass pos around while i really only use it in FlashCardActivity but when I go back from, for example FlashcardChangeActivity it gets recreated which is good, since I want my elements of my RecyclerView to be actualized. I need the pos there since I call a Function in my Database which returns all the elements of a certain Folder which I will display than.
So how do I implement this more clean and better without having to drag around the pos.
(I would also have a UML Classdiagramm and my Code but i think the Picture i drew shows my Problem better)
Related
I am developing an Android Kotlin application which uses two different activities. In each one I have a button that allow me to move to the other one, to say, in Activity 1 I have a button that calls the follwing:
val intentActivity2 = Intent(this, Activity2::class.java)
startActivity(intentActivity2)
This launches correctly Activity2, which similarly inside it I have another button that calls the first activity to return to it:
val intentActivity1 = Intent(this, Activity1::class.java)
startActivity(intentActivity1)
The problem I have is that I want to have both activities running simultaneously (not needed to be shown at screen at the same time), and the issue right now is that every time I call the "startActivity(intent)" a new activity is created, loosing what I had in the previous one, so when I return to Activity1 everything is reset and the same when I go once again to Activity2. Both activities work fine and do their work, the problem is that I can't freely conmute between them.
Is there a way to have both activities at the same time or to not start a new activity everytime I want to change to the other one?
Thank you,
As someone just said you need ViewModel to retrieve your data after deleting/creating new activities. Maybe you can use fragments to do your things. Fragments are attached to activities and it is easier to use them instead of ViewModel.
I am doing a small game, and at the first screen I have made a loading screen. After that I made a second screen. My problem that when I use the emulator it stays on the first screen which is the loading screen. What should I do to connect the first screen with the second?
NOTE: I am using Android Studio, and there is no buttons on the first screen.
If anyone could suggest a video tutorial for my problem, that would be awesome.
Thanks!
You need to have some trigger to call another activity, which in your case it might be when all your data is loaded. It could be something like this:
while(yourDataIsNotLoaded){
//your loading code inside here
}
Intent i = new Intent(getApplicationContext(), SecondActivity.class);
startActivity(i);
Considering that the second screen refers to SecondActivty.
I am currently developing a game with the android development enviornment. And for the past couple of months I've been dealing with a nasty OOM error. My first problem was that I was placing my drawables in the wrong folder (Drawable-xhdpi in drawable folder). But now, the OOM error eventually happens as you go through the game.
It is a rpg, basically compoed of menus in activity layouts with animations and things. and I've tried everything I could to fix it. I've tried the unbindDrawables method:
unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
which does help a lot, but it does not fix the issue. And I cannot use any of the bitmap.factory options or anything, since I load my images through xml in my drawables folder. My images aren't that big by the way, as activities have a background of 720x1280, with some smaller images, and the most total images I'll have on screen at a time is around 8.
So this lead me to think that I may have a memory leak. I did ALOT of research, and I found out that use this(the activity context) will cause a leak, and I should use the application context. However, If I make the switch, there is almost no difference.
So I used MAT to figure out what was going on, and most of my memory is going to byte[], android.graphics.bitmap. And if I drill down to find the cause of this, it seems that java.ref.finalizer is causing all of the retained memory in the VM.
The only reason I could think this is happening, is because whenever I start a new activity I use,
Intent fight = new Intent(this, StartScreen.class);
//add this flag to remove all previous activities
fight.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(fight);
finish();
which opens a new activity, but closes the one we were just in. So, I'm guessing the bitmaps are not being recycled correctly whenever I finish an activity? or is closing and starting activities like this bad for memory?
I've been on Google all day trying to find the solution to this problem and I can't find it. Any soulutions are appreciated, thank you for reading this!
P.S if you would like to see any snippets of my logcat or code or anything, I am more than happy to post it.
P.S P.S My game has about 10-12 different activities I switch between. For example If I have activities A,B,C I open A, Open B close A, Open C close B, open B close C, open A close B.
EDIT: As request about my activities. Usually it is a menu, and when you press a button, that activity finishes, and then moves into another activity. Or buttons will do some math for things like selling, or doing damage to an enemy. One thing about my activity architecture, is that since I am closing every activity as I go to a new one, when I go back to the ones I closed, I am re-creating them. So I don't know if the old activities I finished still have memory in the VM that over time causes the Out Of Memory error, since it all builds up and keeps expanding. I explained My call for a new activity above. And the intent flag closes all past activities (if there are any) in the stack.
EDIT EDIT: As per request my oncreate and onDestroy:
OnCreate:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start_screen);
//setting fonts
//a function that binds views by findview by Id and then sets their typeface
setFont();
//set up the music service
//connects the app to the background music service
playMusic();
//aquire wakelock
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
OnDestroy:
#Override
public void onDestroy()
{
super.onDestroy();
//unbinds the service
unbindService(musicConnection);
//unbind drawables (function above)
unbindDrawables((LinearLayout) findViewById(R.id.container));
}
you should destroy the activities that you don't need anymore it takes place in the memory. or if you dont want your user/player to go back to the recent activity you should finish the activity. and if you will notice. if you dont finish the activity and press the back button several times it is layered.
second you mentioned that it is a game. in android programming you need to consider your bitmap resources so to avoid getting an OOM error in your game make use of sprite sheet it will save a lot of memory and usage of bitmaps in your application. i encountered those kind of situation and bitmaps mainly causes the OOM error.
I will say it depends. but with your problem your answer is right here
Quick quote from the site
Note: In most cases, you should not explicitly finish an activity using these methods.
As discussed in the following section about the activity lifecycle,the Android
system manages the life of an activity for you, so you do not need to finish your own
activities. Calling these methods could adversely affect the expected user experience
and should only be used when you absolutely do not want the user to return to this
instance of the activity.
Read for more info
well i get you lucidly now, but im thinking of what you are tryna do here, so y dont you use FragmentActivity for B and C.. So, Activity A opens B..B is opened as fragment but works like activity-(thats fragmentActivity), and opens C which is most likely a Fragment..which i think would be perfect for your situation..
for more info about FragmentActivity click Here
no more activities back and forth.. and its gonna work like an activity..
I have four activities, ABCD.
The user will initially go ABCD, then the user may want to tap the back button to check something on C before tapping a button on C to take them forward to D again.
The problem I have is that D is running a count down timer which needs to continue counting down and updating on an activity D view. If I currently tap back to go back to C then tap to go forward to D again, the countdown timer is still running but not connected as a new activity has been created for D.
I'd like the user to be able to navigate back to C without it affecting or destroying D so I can keep my timer hooked up to the view.
Finally, if the user clicks back to B, it would destroy both C and D activities (and the countdown timer).
It's quit easy save the timer value and current time on saveInstanceState call back when users leave the activity. When activity recreates use the timer value plus it with (current time - lastSavedTime) and set the timer.
it should work just fine but you can achieve this in better way by using fragments and ViewPager.
In case you didn't used ViewPager before. its a component that let you switch between different views by swiping screen to left or right. By default view pager loads the current view and one near it in both side. so if you are in page 1 (index 0) page 1 and page 2 is loaded. if your are in page 2, page 2, page 1, and page 3 will be loaded and so on. The good news is you can change the number of pages that will load near each fragment using simple code like this
mViewPager.setOffscreenPageLimit(3);
So now all 4 fragments are loaded. So you have 4 fragments all loaded on screen. According to developers.android.com all the others views (except one on screen) are loaded but in idle state so I don't think you can have your timer inside fragment D. But that wouldn't be a problem because you only have one activity. Implement your timer in the one and only activity you've got and it will work fine because this activity will not be destroyed when pages change. But you still need to save the same data (timer data + current time) because activity may stop due to user switching to another app.
last thing you need to do is accessing timer data inside your fragment. I will not explain how since there is so many tutorial on how to communicate between activities and fragments but just to give you and idea you need to declare an interface inside your fragment, implement this interface in activity and use this interface inside your fragment to access timer data.
The second solution is a lot more complex but it gives the user a better experience and performance increase is noticeable. Decide witch one is best for you. Good luck
You can use this
#Override
public void onBackPressed() {
Intent intent = new Intent(this, C.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
to put your D activity to background and then resume it from C like this
Intent intent = new Intent(this, D.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
However, you should use a service for this sort of background tasks.
Perhaps I'm not used to the Android development, but when I look, I expect everything to be done in order. When one activity finishes, the next starts. However, it seems that my code doesn't work that way. Take the following code for example:
for (int i = 0; i < 3; i++){
Intent myIntent = new Intent(Game.this.getBaseContext(), NextScreen.class);
myIntent.putExtra("something", i);
myIntent.putExtra("Opp", oppList.get(i).toString());
startActivityForResult(myIntent, 0);
}
It doesn't display activity one, wait for you to do what you do in that screen, then come back for the second activity. It immediately displays the third activity. If I click on the back button on my android emulator, it will show me activity two... and if I click back again, it will show me activity one... so it just kind of rapid-fires these activities onto the screen without waiting for you to do what you do in these activities. I'm sure I'm not the first person that's wanted to do something like this. Any idea what I'm doing wrong? How do you work around this situation?
Activities execute asynchronously. One way to serialize this is to chain the activites in your onActivityResult method. Pass to each (sub)activity an activity number, starting with 0 and have the sub-activity return it as part of the result. Your onActivityResult logic can deal with the response, then examine the activity number and fire the next activity (if there is one).
I don't believe you can queue up pages like this in 1 handy function. You'd be better off having a function nextPage which takes the current activity have moves the user to the next activity. This could be called everytime the user is ready to proceed to the next page (triggered by a button press or something).
Or just start the next activity on the button press directly