Issue
I'm currently facing something which is really weird with my cell phone. If I use the app I'm developing I have no problems, until I stop using it for a long time (when this happens the instance of the app gets closed I believe). I downloaded an app which "fills your RAM" in order to emulate this behavior. What I don't understand is the error: Every time I try using the app after I've filled the RAM I get a ResourceNotFound exception, which doesn't make sense to me, at least. As you can see by the trace, the error is in the following line:
mView = inflater.inflate(mLayout,container, false);
Here's the trace:
11-25 08:22:09.496: E/AndroidRuntime(6386): FATAL EXCEPTION: main
11-25 08:22:09.496: E/AndroidRuntime(6386): Process: com.papinotas, PID: 6386
11-25 08:22:09.496: E/AndroidRuntime(6386): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.papinotas/com.papinotas.views.activities.TeacherMainActivity}: android.content.res.Resources$NotFoundException: Resource ID #0x0
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2305)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.ActivityThread.access$900(ActivityThread.java:161)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.os.Handler.dispatchMessage(Handler.java:102)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.os.Looper.loop(Looper.java:157)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.ActivityThread.main(ActivityThread.java:5356)
11-25 08:22:09.496: E/AndroidRuntime(6386): at java.lang.reflect.Method.invokeNative(Native Method)
11-25 08:22:09.496: E/AndroidRuntime(6386): at java.lang.reflect.Method.invoke(Method.java:515)
11-25 08:22:09.496: E/AndroidRuntime(6386): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
11-25 08:22:09.496: E/AndroidRuntime(6386): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
11-25 08:22:09.496: E/AndroidRuntime(6386): at dalvik.system.NativeStart.main(Native Method)
11-25 08:22:09.496: E/AndroidRuntime(6386): Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x0
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.content.res.Resources.getValue(Resources.java:2036)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.content.res.Resources.loadXmlResourceParser(Resources.java:3265)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.content.res.Resources.getLayout(Resources.java:1852)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
11-25 08:22:09.496: E/AndroidRuntime(6386): at com.androidinit.base.PlaceHolderFragment.onCreateView(PlaceHolderFragment.java:29)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.Fragment.performCreateView(Fragment.java:1700)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1044)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1853)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.Activity.performCreate(Activity.java:5429)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
11-25 08:22:09.496: E/AndroidRuntime(6386): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269)
11-25 08:22:09.496: E/AndroidRuntime(6386): ... 11 more
11-25 08:22:09.506: W/ActivityManager(847): Force finishing activity com.papinotas/.views.activities.TeacherMainActivity
11-25 08:22:09.516: W/ContextImpl(847): Calling a method in the system process without a qualified user: android.app.ContextImpl.sendBroadcast:1479 com.android.server.am.ActivityStack.startPausingLocked:1006 com.android.server.am.ActivityStack.finishActivityLocked:3162 com.android.server.am.ActivityStack.finishTopRunningActivityLocked:3005 com.android.server.am.ActivityStackSupervisor.finishTopRunningActivityLocked:3142
11-25 08:22:09.526: D/CrashAnrDetector(847): processName: com.papinotas
11-25 08:22:09.526: D/CrashAnrDetector(847): broadcastEvent : com.papinotas data_app_crash
11-25 08:22:09.526: V/SmartFaceService - 3rd party pause(847): onReceive [android.intent.action.ACTIVITY_STATE/com.papinotas/pause]
11-25 08:22:09.526: W/ContextImpl(847): Calling a method in the system process without a qualified user: android.app.ContextImpl.sendBroadcast:1479 com.android.server.analytics.data.collection.application.CrashAnrDetector.broadcastEvent:296 com.android.server.analytics.data.collection.application.CrashAnrDetector.processDropBoxEntry:254 com.android.server.analytics.data.collection.application.CrashAnrDetector.access$100:60 com.android.server.analytics.data.collection.application.CrashAnrDetector$1.onReceive:102
Here's the complete class of the trace:
package com.androidinit.base;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class PlaceHolderFragment extends Fragment {
private int mLayout;
private View mView;
private BaseActivity mActivity;
public PlaceHolderFragment() {
}
public PlaceHolderFragment(int mLayout, BaseActivity mActivity) {
this.mLayout = mLayout;
this.mActivity = mActivity;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mView = inflater.inflate(mLayout,container, false);
mActivity.setActivityView(mView);
return mView;
}
}
Also, here's the methods I believe might be important in BaseActivity, which I use to create all my activities (all my activities extend BaseActivity)
public class BaseActivity extends Activity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
@Override
protected void onCreate(Bundle savedInstanceState) {
session = new SessionManager(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.ai_base_activity);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
@Override
public void onResume(){
super.onResume();
setSpinner();
}
public void createFragmentView(int layoutId) {
//FIXME agregar la clase hija
mFragment = new PlaceHolderFragment(layoutId, this);
getFragmentManager().beginTransaction().add(R.id.container, mFragment).commit();
}
public PlaceHolderFragment getPlaceHolderFragment( ) {
return mFragment;
}
}
I haven't found any solutions to this problem, which is occurring in my Galaxy S4, Android 4.4.3. Any help would be greatly appreciated.
Solution
You are getting a ResourceNotFoundException
because you are requesting to load a resource with an ID of 0.
You are requesting to load a resource with an ID of 0
because mLayout
is 0.
mLayout
is 0 because it is a data member of your fragment, and your fragment is being recreated, probably because your process was terminated while you were in the background.
Frankly, IMHO, passing in a layout ID to a fragment is a code smell, and passing in BaseActivity
is a flat-out bug in your code. If your fragment needs an activity, call getActivity()
on the fragment. Delete the two-parameter constructor entirely.
Assuming that there is actually a legitimate reason to pass in a layout ID, use the factory method pattern and the arguments Bundle
, instead of your two-argument constructor. The arguments Bundle
is automatically saved as part of the instance state of your fragment, and therefore it will not be lost when your process is terminated and later re-created.
I use the factory method/arguments Bundle
pattern in this sample project, so that the fragment knows what page of the ViewPager
it is. That position
is stored in the arguments Bundle
and is retrieved from that Bundle
when the fragment needs it:
/***
Copyright (c) 2012-14 CommonsWare, LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
From _The Busy Coder's Guide to Android Development_
http://commonsware.com/Android
*/
package com.commonsware.android.pager;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
public class EditorFragment extends Fragment {
private static final String KEY_POSITION="position";
static EditorFragment newInstance(int position) {
EditorFragment frag=new EditorFragment();
Bundle args=new Bundle();
args.putInt(KEY_POSITION, position);
frag.setArguments(args);
return(frag);
}
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View result=inflater.inflate(R.layout.editor, container, false);
EditText editor=(EditText)result.findViewById(R.id.editor);
int position=getArguments().getInt(KEY_POSITION, -1);
editor.setHint(String.format(getString(R.string.hint), position + 1));
return(result);
}
}
Answered By - CommonsWare
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.