It is not working, and Right place to implement onSaveInstanceStance() - android

I am trying to grasp the concept of life cycle call back methods of an activity and what happens inside them.
I am writing a small activity class which just displays a text.
The Problem is that the activity starts to display and i get a dialog saying "unfortunately Activity Lifecycle and Coordination has stopped working"
Please tell me how to fix this.
The code is as follows:-
package com.practice.lifecycle_coordination;
//import android.app.ActionBar;
import android.app.Activity;
//import android.os.Build;
import android.os.Bundle;
class MainActivity extends Activity{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
protected void onStart(){
super.onStart();
}
protected void onResume(){
super.onResume();
}
protected void onPause(){
super.onPause();
}
protected void onStop(){
super.onStop();
}
public void onSaveInstanceState(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
}
}
LAYOUT FILE:-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#+string/title"
android:gravity="center_horizontal"
android:textStyle="bold" />
</LinearLayout>
STRINGS RESOURCE FILE:-
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Activity LifeCycle</string>
<string name="action_settings">Settings</string>
<string name="title">MAIN ACTIVITY</string>
</resources>
Is onSaveInstanceState() implemented at the right place? In case I want to save some additional data into the bundle, is this the right place to implement it?
I know that I don't need to write any life cycle call back methods except onCreate(). But I just wanted to check.

You don't have to write onCreate() actually. The only life cycle methods you have to write are ones in which you need to override and implement your own code within. onCreate() is overwritten in virtually every Activity, however, because you typically are going to want to use this point in the life cycle to initialize variables etc.
As for Is onSaveInstanceState() implemented at the right place?
Yes. The order within your Activity in which your life cycle methods occur doesn't matter in the slightest. As long as you're in the right activity, you're fine. These methods are called automatically as your activity goes through those life cycle stages.
As for what's actually wrong with the current code? We'll need a lot more information. Your logcat will give you some information on what actually caused the crash. Post that, and your problem can be better diagnosed.

Related

How to use AndroidBootstrap without extends Application

I am trying to use Android Bootstrap library. I followed Quick Start. In Quick Start, it says I should override my class like this:
public class SampleApplication extends Application {
#Override public void onCreate() {
super.onCreate();
TypefaceProvider.registerDefaultIconSets();
}
}
How can I use this library without extending Application class? I want to use this library in my Activity classes.
LoginActivity:
public class Login extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TypefaceProvider.registerDefaultIconSets();
setContentView(R.layout.activity_login);
}
}
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.merve.tev.Login">
<com.beardedhen.androidbootstrap.BootstrapDropDown
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:bootstrapText="Medium {fa_thumbs_o_up}"
app:bootstrapBrand="regular"
app:roundedCorners="true"
app:bootstrapSize="md"
app:dropdownResource="#array/bootstrap_dropdown_example_data"
app:bootstrapExpandDirection="down"
tools:layout_editor_absoluteY="202dp"
tools:layout_editor_absoluteX="115dp" />
</LinearLayout>
In my MainActivity class, I placed the button. When I click it, I should go LoginActivity class. However, I get an error:
java.lang.RuntimeException: Unable to start activity ComponentInfo: android.view.InflateException: Binary XML file line #11: Binary XML file line #11: Error inflating class com.beardedhen.androidbootstrap.BootstrapDropDown
In your activity class:
In onCreate() Method, write this line before setContentView();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TypefaceProvider.registerDefaultIconSets();
}
I hope it will work.
It's recommended to invoke TypefaceProvider.registerDefaultIconSets(); in your application class because that will load the FontAwesome typeface, before any views are displayed on screen.
If you're not loading FontAwesome icons then you can skip this step. If you're worried about startup time then you could try performing it asynchronously.
Finally, if you know for a fact that your app will always launch from a certain activity, then you can call TypefaceProvider.registerDefaultIconSets(); before setContentView is called, and should still be able to use FontAwesome icons.
The only tradeoff here is that most apps have multiple Activities which act as entry points, meaning you might have to add this setup logic to multiple places. That's why the current advice is to set it up in your Application class - you'll only ever need to initialise it once.

Android WebView re-rendering UI after changing orientation.

In My application i am setting orientation of the application on button click, using setRequestedOrientation(), My application has one webview which displays local web page.
I am using solution as mentioned in below link, to stop reloading of page when orientation changes.
http://www.devahead.com/blog/2012/01/preserving-the-state-of-an-android-webview-on-screen-orientation-change/
Only difference is that i am not having onSaveInstanceState and onRestoreInstanceState in my activity.
What happens in my case is that, my web view does not reload when i change the orientation but it just re-renders the UI upon changing the orientation.
It happens like it first displays the UI and then it displays the white blank screen for few seconds and then again it displays UI.
How can i workaround it?
Once upon a time I used their implementation however I after reading up on the Android documentation I realized that much of their code was pointless since registering for config changes (in the manifest) means that your activity won't be destroyed as it normally is.
Long story short, you don't need to use a FrameLayout as a container for your webView, you may not need onConfigurationChanged, etc. If I get some time I will post some code as an example.
For now, make sure you have the following in your manifest file
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
instead of
android:configChanges="keyboard|keyboardHidden|orientation"
since on orientation change devices may get get a screenSize change
EDIT This is what I have done (skimmed from one of my projects so I may have missed minor details)
in AndroidManifest.xml
<activity android:name=".Activities.WebWrapperActivity"
android:theme="#android:style/Theme.NoTitleBar"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"/>
web_wrapper_activity_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView android:id="#+id/web_wrapper_activity_web_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbarStyle="outsideOverlay"/>
</LinearLayout>
The Activity (or a portion of it)
public class WebWrapperActivity extends Activity {
private WebView _webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.web_wrapper_activity_layout);
init();
}
private void init() {
_webView = (WebView) findViewById(R.id.web_wrapper_activity_web_view);
_webView.setScrollbarFadingEnabled(true);
_webView.getSettings().setLoadsImagesAutomatically(true);
_webView.getSettings().setJavaScriptEnabled(true);
_webView.getSettings().setAllowFileAccess(true);
_webView.getSettings().setSavePassword(false);
_webView.getSettings().setPluginState(WebSettings.PluginState.ON);
_webView.loadUrl(“http://www.google.com”);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
_webView.saveState(outState);
}
}
As i mentioned previously, you may not need onConfigurationChanged if your webView is the only view in the Activity.
If you have any issues let me know

How can I access views in activities within a TabActivity?

I've got a TabActivity containing other activities intended to split up a form. The TabActivity has in its layout a button intended to collect the data from all the form-related views across all the activities contained within the TabActivity and store it. The problem I'm running into is that the TabActivity doesn't appear to have access to these views; when I call findViewById() with one of them, I get a NullPointerException.
The documentation seems sparse about exactly how TabActivity works with respect to controlling the activities it contains. If it destroys an activity when switching from it to a different one, the situation I'm in would make sense. I'd like to know the best approach for accomplishing the goal described above.
src/com/vendor/MyTabActivity.java:
public class MyTabActivity extends TabActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_tab_activity);
final Button saveButton = (Button) findViewById(R.id.save_button);
saveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// NullPointerException happens here
String fieldValue = ((TextView) findViewById(R.id.text_field)).getText().toString();
}
});
}
}
res/layout/my_tab_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost">
<LinearLayout>
<TabWidget android:id="#android:id/tabs"/>
<FrameLayout android:id="#android:id/tabcontent" />
<Button android:id="#+id/save_button"/>
</LinearLayout>
</TabHost>
src/com/vendor/NestedActivity.java:
public class NestedActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nested_activity);
}
}
res/layout/nested_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout>
<EditText android:id="#+id/text_field"/>
</RelativeLayout>
</ScrollView>
Your problem comes from these two lines in MyTabActivity...
setContentView(R.layout.my_tab_activity);
...and...
String fieldValue = ((TextView) findViewById(R.id.text_field)).getText().toString();
...although you obviously know the findViewById(R.id.text_field) is what's causing it.
Using findViewById(...) only works when trying to access UI elements which have been inflated as part of your current Activity. As there isn't a TextView with the resource id of R.id.text_field in the my_tab_activity.xml, it's never going to work.
Accessing activities which are tab content from the TabHost / TabActivity is tricky. My suggestion would be to use SharedPreferences which can be accessed from everywhere in your app. Once a TextView (or any other user-input item) is changed, save it to a SharedPreferences using a 'key' which identifies which activity/tab it came from. From then on, the TabActivity can collate the data easily.
You can get a reference to activities running inside of the tab activity using getLocalActivityManager() or getCurrentActivity(). For the activity object you get back you can do activity.findViewById() to get a reference to a view inside of the specific activity. But to point out TabActivity has been deprecated and you should be using Fragments to do what you are looking for. If you are targeting a version of Android earlier than 3.0 you can use the compatibility library to access fragments.

please explain this block of code

I found this on android developers when i was trying to program a button:android developers blog: UI framework changes in Android 1.6
With Android 1.6, none of this is necessary. All you have to do is declare a public method in your Activity to handle the click (the method must have one View argument):
class MyActivity extends Activity { public void myClickHandler(View target){
// Do stuff
}
}
And then reference this method from your XML layout:
<Button android:onClick="myClickHandler" />
can smeone please explain this code to me? I am a beginner in programming, and I don't know what to put in the //do stuff space? I need to reference another activity so i can open another screen. And do i still need to have an activity and put a block of program in the class? this is the code i am using in the class at the moment. Please tell me if i need to update it to use this method:
package com.duncan.hello.world;
import com.duncan.hello.world.R;
import android.app.Activity;
import android.os.Bundle;
public class OtherActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other);
}
}
You put what you want to happen when the button is clicked in the // do stuff part.
You only need to update your code if you're using a button click handler in this fashion.
You might want to start with something a bit simpler, and perhaps not target Android 1.6.

Simple activity switch not working. No Errors

I have a basic calculator app I'm making. Two activities, the main one and ResultView.
I've made it where I click a button on activity A to go to activity B. The log says activity B is started and "displayed" successfully, the title for the new activity loads, but the body does NOT show. I added a simple Text view with static text.. see the result.xml at the bottom. I also tried inserting information programmatically, but that didn't do.
When I debug the program, I tried putting breakpoints as the activity is called with startActivity() as well as on the first line of the onCreate method within the ResultView class (my activity "B") but the program never hits the second breakpoint. In fact, it looks as if Looper.class is called in the end.
This bit of code is placed in the button handler on acitivity A:
i.putExtra("test1",34);
i.putExtra("test2",35);
this.startActivity(i);
This in the onCreate function in activity B:
public void OnCreate(Bundle
savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.result);
}
The activity is in the manifest, within the "application" tag:
<activity
android:name="ResultView"></activity>
If I didn't supply enough info, let me know.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llParent"
android:orientation="vertical"
android:padding="10dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:text="HELLO WORLD"
/> </LinearLayout>
If more info is needed, let me know...in short, "HELLO WORLD" does not display at all.
It's not OnCreate, it's onCreate (lowercase o). Otherwise the method won't be overriden. The #override annotation has no effect if it's omitted, it's just for readability for the programmer.
Are you sure that the public void line or the line before that contains #Override? If not, you're not overriding the OnCreate method. The code should read
#Override public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.result);
}
EDIT
Of course the "O" must not be a capital "O"...

Categories

Resources