I am using setContentView(R.layout.main) to switch the views in the same activity. I am calling some asynchronous task and populating the data on the main layout file after that I am changing the view by calling setContentView(R.layout.main) method.
I came to know that we should not use setContentView method multiple times for same activity. Though it is working fine for me.
Can anyone explain why we should not use setContentView method multiple times for the same activity to change the views?
Will it create any memory related exceptions? Could someone please clarify?
I think switching Views is not a good idea, because android platform already have strong framework to handle the transition in between the views and maintaining the state of each view associated with the Activity its always better to stick with the existing framework instead of thinking of some complex implementation that you have to go through to do all these things. If you do not need any of these things to taken care in your application and if only if you have only two or three screen in your entire application you can try switching the views. That even based on how your views are structured if you have complex logic and lot of data needed to create these views this wont be a good way of doing it.One more thing if you are adding more views say functionality to your application the load that need to be handled by the Activity will go high. In this case you will be declaring and initializing all views inside that particular Activity so maintaining all these views instances is heavy. If you want to know more about the Activty and Task kindly refer this link
Well every time you call setContentView() you'll have to find all the layouts again besides that I think you "can" do it. But as discussed here this is ill adviced as it clearly goes against the android guidelines. Also Commonsware have some very important points here one of the most important being that you will be prone to leak memory as you forget to clean up stuff from your views etc. which Android normally would handle for you.
In short you should follow Android guidelines and use Fragments or start a new Activity.
According to the developer docs setContentView(int layoutResID) is used to
Set the activity content from a layout resource. The resource will be inflated, adding all top-level views to the activity.
In best practice this method is used to Inflate your Activity layout on start up. This does not mean that it will cause issues in the future if you keep using this method. To quote a answer in this question
The setContentView on your Activity actually calls the setContentView on the Window used by the activity, which itself does a lot more than just inflating the layout.
I suggest that you find a alternative way to switch layouts like using a ViewPager with Fragments or some other Tabbing approach but in the end it all comes down to what you want to do.
This question might also give you what you're looking for.
Related
I'm new to android development and I see there are 2 different ways to make a button perform a specific task.
The 1st way is to have a setOnClickListener() within your onCreate function.
The 2nd is to create a separate method in its Activity page and call it using the activity's XML using android:onClick="thisFunction"
I have always found it easier to call functions using android:onClick in the XML.
Would this way make the buttons perform slower?
When would you experts prefer one way over another?
In my opinion, it's always better to set the onClick in the code, since the xml way only works well with activities. When you try to do that with fragments, it will ask you to choose an activity to handle the onClick() from the xml. Imagine having a single activity app, with lots of fragments, and having all of it's onClick() methods spread across the MainActivity code. It's quite a mess.
Regarding performance setOnClickListener() vs onClick() inside xml, I think it's pretty much the same nowadays.
I've been reading about the include tag on xml, fragments to use on layout for smartphone and tablets but I'm getting more confused than getting a solution to my problem.
My App has 4 screens.
1 - You login and it download info from a json
2,3,4 - From login, Activity 2 load (A list with custom adapter), where you can click one of 2 images to jump to 3rd and 4th activity.
I need now to create the activity 1, 2, and 3 again with different JSONs being parsed, with 1 and 2 having the same layout of the existent ones and 3 with a different layout.
The code I need for them to work is(or can be) the same (Download Task with AsyncTask, button click listeners, etc) I already have for those activities.
I think it's not a goot pratice to copy basically the same getView method, for example, and paste on a new class, right? The buttons wouldn't work on the second range of screens for example.
So, what approach should I take that isn't copy and paste code and change things manually?
Sorry for the newbie question.
If needed I can provide code.
PS 1: I've already did tests with include on xml and copy code but that doesnt look professional
PS 2: Is fragments only for different screens like tablet or I could make something with it?
That's several questions, so here's several answers, including to some un-asked questions:
To the greatest extent possible, strive to remove as much code as possible from your Activities, Fragments, etc. If it doesn't have anything to do with the Android lifecycle or actually putting something on the screen (e.g. parsing JSON), put it in a "plain old java" class. Also, this way, you can share the functionality among Activities.
IMHO, you should never use an AsyncTask, for any reason. They're used with an Activity or Fragment, but don't respect the Fragment or Activity lifecycle, so are often the cause of crashes that can be difficult to diagnose. Use something synchronized with the lifecycle, like a Loader. Or go the RxJava route, where Subscribers can be canceled at the appropriate point in the Activity/Fragment lifecycle.
Fragments can be good for code re-use, but they have a slightly different lifecycle from Activities, so they can be difficult to work with, so use them sparingly and be careful. If you're doing it just to re-use a bit of UI (but not behavior), a layout "include" is probably better. For behavior, a custom View class can be a good alternative to a Fragment.
Don't do HTTP / REST access yourself, using primitives like HTTPUrlConnection. There are a lot of corner cases that are going to get you into trouble. Use one of the several really good open-source libraries that are built for this purpose. I highly recommend Retrofit.
Good day,
I'm working on an application that will serve as a monitor of some sort for drivers. My client would like the application to work regardless of the orientation of the device.
I implemented the solution provided in the following article , and after fiddling a bit with the debugger, I can see that the Asynctask is still working. However, the TextViews and ImageViews it is supposed to work on are not working anymore.
Here is the code of my TaskFragment.
To clarify : The AsyncTask still receive and handle the elements correctly, but the elements of the layout are not updated anymore. I would like to know how I can keep them working.
I would suggest using an AsyncTaskLoader as those can re-attach to whatever lifecycle element you created it in relatively easily. See here: https://developer.android.com/reference/android/content/AsyncTaskLoader.html
It might seem pretty involved to implement at first, however if you read https://developer.android.com/guide/components/loaders.html, most of the weirdness should be cleared up.
TLDR: Using AsyncTaskLoader allows an easy way for your AsyncTask to be reattached to your fragment after it is destroyed and recreated. You just need to call getLoaderManager().initLoader(...) in the onCreate of your fragment.
Ok, so I found a (probably not very efficient) workaround, but a workaround nonetheless.
The problem was that, after an orientation change, since the Activity is destroyed and recreated, the variables batterymonitor, valuemonitor, etc, would not point towards the new objects created because of the layout/activity change.
As a solution, I am now using a findViewById each time I need to do an operation on the layout. This way, the id is permanently refreshed to keep up with the activity changes on a rotation of the device.
The ugly line I use to do so is :
batteryMonitor = (ImageView)getActivity().findViewById(R.id.batteryMonitor);
batteryMonitor.setImageResource(R.drawable.no_battery);
Im looking through a project here and it has a way of using onClick that is different to what ive seen any other time.
Usually you set the listener for the button during onCreate or whatever.
Here in the activities xml it has android:onClick="navigateToUrl". Then this seems to kick off the method navigateToUrl in the classes code.
Im just wondering what is the difference between the two methods?
They work the same way. With the xml version, the framework adds an onClickListener during inflation that uses reflection on the Context its called from looking for a function with that name, and calls it. So its slightly less efficient, but not enough to really get worried about. The big advantage is a less cluttered onCreate, the big disadvantage is that to figure out what a view does when clicked you have to read xml rather than code. Which you use is a matter of personal preference. I'm currently in the explicit onClickListener group, because I prefer not to have behind the scenes magic.
For the latter, you need to keep a public method always. If you do not want to keep your method publicly visible, you would prefer to have a listener implemented.
I am making a game where I will go from my main screen to a battle screen and the back when the battle is finished. Is it better to have the two screens as separate activities or can I get by using the setContentView(R.layout.screen2)?
I've been trying to get the activity screen switching to work but everytime I try it, my phone tells me that the app isn't responding. If it is better to use the activities, then I'll take the time to work it out, but for now I'll take the easy way out to get things working.
Calling setContentView() multiple times is not recommended. The normal way to switch between layouts in the same activity is to use a ViewFlipper or FrameLayout (see Calling setContentView() multiple times and How can i make a dynamic flipping screen(like that of iPhone) in Android)
Alternatively you could use ViewSwitcher, which seems to fit your needs pretty well. There's a good detailed tutorial available at http://inphamousdevelopment.wordpress.com/2010/10/11/using-a-viewswitcher-in-your-android-xml-layouts/
The simplest way to change view of an activity dynamically would be to inflate the target view into the activity's root ViewGroup (FrameLayout preferably). This is just a one line code
inflater.inflate(R.layout.target_view,(ViewGroup)findViewById(R.id.activity_root_viewgroup), true);