I have made an app in compatibility mode which supports Android 4.4 up to Android 2.2 (Foroyo). Well I am testing it on Android 4.0.4 and Android 2.2 (real devices). My app crashes on Android 2.2.
Let me explain my scenario. I have an activity with 11 fragments in tabbed mode. What I am doing is I'm executing a Google Street view from a fragment via intent, like this:
Intent streetView = new Intent(android.content.Intent.ACTION_VIEW,
Uri.parse("google.streetview:cbll=" + 40.720032 + ","+ -73.988354 + &cbp=1,99.56,,1,-5.27&mz=21"));
startActivity(streetView);
Here is my MainActivity code. Please see my onCreate()
, onStart()
, onPause()
, onResume()
, and onDestroy()
method:
public class MainActivity extends SherlockFragmentActivity {
private ArrayList<Class> classes = new ArrayList<Class>();
private Intent intent;
@SuppressWarnings("unchecked")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
classes.add(OverView.class);
classes.add(LifeStyle.class);
classes.add(RealState.class);
classes.add(Events.class);
classes.add(Deals.class);
classes.add(Popular.class);
classes.add(MetroBusStops.class);
classes.add(Schools.class);
classes.add(Libraries.class);
classes.add(Parks.class);
classes.add(PublicSafety.class);
// Set up the action bar.
final com.actionbarsherlock.app.ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);
Tab tab = null;
for (int i = 0; i < classes.size(); i++) {
tab = actionBar
.newTab()
.setText(
getResources().getStringArray(R.array.tabs_names)[i])
.setTabListener(
new TabListener<SherlockFragment>(this, "Tab" + i,
(Class<SherlockFragment>) classes.get(i)));
actionBar.addTab(tab);
}
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Log.e("onCreate Activty", "Called");
}
@Override
protected void onStart() {
Log.e("onStart Activty", "Called");
super.onStart();
}
@Override
protected void onResume() {
Log.e("onResume Activty", "Called");
super.onResume();
}
@Override
protected void onPause() {
Log.e("onPause Activty", "Called");
super.onPause();
}
@Override
protected void onDestroy() {
Log.e("onDestroy Activty", "Called");
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getSupportMenuInflater().inflate(R.menu.main, menu);
return true;
}
public static class TabListener<T extends SherlockFragment> implements
ActionBar.TabListener {
private SherlockFragment mFragment;
private final SherlockFragmentActivity mActivity;
private final String mTag;
private final Class<T> mClass;
/**
* Constructor used each time a new tab is created.
*
* @param activity
* The host Activity, used to instantiate the fragment
* @param tag
* The identifier tag for the fragment
* @param clz
* The fragment's Class, used to instantiate the fragment
*/
public TabListener(SherlockFragmentActivity activity, String tag,
Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
/* The following are each of the ActionBar.TabListener callbacks */
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// Check if the fragment is already initialized
if (mFragment == null) {
// If not, instantiate and add it to the activity
mFragment = (SherlockFragment) SherlockFragment.instantiate(
mActivity, mClass.getName());
ft.add(android.R.id.content, mFragment, mTag);
} else {
// If it exists, simply attach it in order to show it
ft.attach(mFragment);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
// Detach the fragment, because another one is being attached
ft.detach(mFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// User selected the already selected tab. Usually do nothing.
}
}
@Override
public void onBackPressed() {
finish();
overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
}
}
Testing on Android 4.0.4
It's working just fine. Here is my activity life cycle's Log of MainActivity in which I'm making tabs and fragments.
While starting my activity for the first time:
onCreate Activty Called
onStart Activty Called
onResume Activty Called
Started Google StreetView via intent from certain fragment
onPause Activty Called
After closing the street view by BackKey Press
onStart Activty Called
onResume Activty Called
Testing on Android 2.2
I'm doing same thing here in Android 2.2 but here the life cycle of activity is some different. Here is my activity life cycle's Log
While starting my activity for the first time.
onCreate Activty Called
onStart Activty Called
onResume Activty Called
Started Google StreetView via intent from certain fragment
onPause Activty Called
After closing the street view by BackKey Press
onCreate Activty Called (Look this. Why is it called here again? This is Odd behaviour)
onStart Activty Called
onResume Activty Called
It's also re-creating my whole activity including Tabs and fragments. It looks restarted my app. And now If I click on any tab its just crash and gives null pointer exception.
Here is the logcat
01-17 12:53:18.968: E/AndroidRuntime(2596): FATAL EXCEPTION: main
01-17 12:53:18.968: E/AndroidRuntime(2596): java.lang.NullPointerException
01-17 12:53:18.968: E/AndroidRuntime(2596): at fragment.populor.Popular.onCreateView(Popular.java:72)
01-17 12:53:18.968: E/AndroidRuntime(2596): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
01-17 12:53:18.968: E/AndroidRuntime(2596): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
01-17 12:53:18.968: E/AndroidRuntime(2596): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
01-17 12:53:18.968: E/AndroidRuntime(2596): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
01-17 12:53:18.968: E/AndroidRuntime(2596): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
01-17 12:53:18.968: E/AndroidRuntime(2596): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
01-17 12:53:18.968: E/AndroidRuntime(2596): at android.os.Handler.handleCallback(Handler.java:587)
01-17 12:53:18.968: E/AndroidRuntime(2596): at android.os.Handler.dispatchMessage(Handler.java:92)
01-17 12:53:18.968: E/AndroidRuntime(2596): at android.os.Looper.loop(Looper.java:123)
01-17 12:53:18.968: E/AndroidRuntime(2596): at android.app.ActivityThread.main(ActivityThread.java:4627)
01-17 12:53:18.968: E/AndroidRuntime(2596): at java.lang.reflect.Method.invokeNative(Native Method)
01-17 12:53:18.968: E/AndroidRuntime(2596): at java.lang.reflect.Method.invoke(Method.java:521)
01-17 12:53:18.968: E/AndroidRuntime(2596): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-17 12:53:18.968: E/AndroidRuntime(2596): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-17 12:53:18.968: E/AndroidRuntime(2596): at dalvik.system.NativeStart.main(Native Method)
Here is the code of my fragment:
public class Popular extends SherlockFragment implements OnClickListener,
OnItemClickListener {
public Popular() {
}
private View v;
private ListView listView;
private RelativeLayout rel_list, rel_map;
private Button btnList, btnMap;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (v != null) {
ViewGroup parent = (ViewGroup) v.getParent();
if (parent != null)
parent.removeView(v);
}
try {
v = inflater.inflate(R.layout.populor_fragment, container, false);
} catch (InflateException e) {
}
listView = (ListView) v.findViewById(R.id.listView1);
rel_list = (RelativeLayout) v.findViewById(R.id.rel_list);
rel_map = (RelativeLayout) v.findViewById(R.id.rel_map);
btnList = (Button) v.findViewById(R.id.btnList);
btnMap = (Button) v.findViewById(R.id.btnMap);
listView.setAdapter(new MyListAdapter());
return v;
}
@Override
public void onStart() {
super.onStart();
btnList.setOnClickListener(this);
btnMap.setOnClickListener(this);
listView.setOnItemClickListener(this);
}
private class MyListAdapter extends BaseAdapter {
@Override
public int getCount() {
return listItems.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.populor_list_items,
parent, false);
TextView txtCategoryName = (TextView) rowView
.findViewById(R.id.txtCategory);
txtCategoryName.setText(listItems.get(position));
return rowView;
}
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int arg2,
long arg3) {
// Clear All previous items colors
for (int j = 0; j < adapterView.getChildCount(); j++)
adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);
// change the background color of the selected element
view.setBackgroundColor(Color.LTGRAY);
showStreetView();
}
private void showStreetView() {
Intent streetView = new Intent(android.content.Intent.ACTION_VIEW,
Uri.parse("google.streetview:cbll=" + 40.720032 + ","
+ -73.988354 + "&cbp=1,99.56,,1,-5.27&mz=21"));
startActivity(streetView);
}
}
Did I have done something wrong in onCreateView()
of my fragment. If so then why is it working fine on Android 4.0.4?