How to resolve android InflateException in Binary XML file crash? - java

In my scenario, I have developed CustomSeekbar long back ago. Now, due to Android X version update, my application getting crash “android.view.InflateException: Binary XML file line”, based on my code analysis, I found the issue happening by overriden setProgress() – which is called from ProgressBar's constructor – and there we are calling onSizeChanged().
As of now nothing much reference about this issue in developer community. If any one knows about this issue, Please help me on this.
Stack Trace
2020-06-13 15:36:44.462 25054-25054/com.goom.project_532 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.goom.project_532, PID: 25054
android.view.InflateException: Binary XML file line #120 in com.goom.project_532:layout/fragment_one_control: Binary XML file line #58 in com.goom.project_532:layout/fragment_two_control:: Error inflating class com.kimso.sims.CustomSeekBar
Caused by: android.view.InflateException: Binary XML file line #58 in com.goom.project_532:layout/fragment_two_control:: Error inflating class com.kimso.sims.CustomSeekBar
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at android.view.LayoutInflater.createView(LayoutInflater.java:854)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1006)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1126)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.parseInclude(LayoutInflater.java:1263)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1119)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1126)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1126)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.inflate(LayoutInflater.java:682)
at android.view.LayoutInflater.inflate(LayoutInflater.java:534)
at com.semcon.jimsa.cfx.fragment.gymControlFragment.onCreateView(gymControlFragment.java:407)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2439)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:620)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
at com.semcon.jimsa.roboguicehelper.KubaAppCompatActivity.onStart(KubaAppCompatActivity.java:141)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1433)
at android.app.Activity.performStart(Activity.java:7978)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3512)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2175)
2020-06-13 15:36:44.464 25054-25054/com.goom.project_532 E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7860)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void java.util.List.clear()' on a null object reference
at android.widget.AbsSeekBar.updateGestureExclusionRects(AbsSeekBar.java:1001)
at android.widget.AbsSeekBar.setThumbPos(AbsSeekBar.java:985)
at android.widget.AbsSeekBar.updateThumbAndTrackPos(AbsSeekBar.java:878)
at android.widget.AbsSeekBar.updateDrawableBounds(AbsSeekBar.java:1942)
at android.widget.ProgressBar.onSizeChanged(ProgressBar.java:2196)
at android.widget.AbsSeekBar.onSizeChanged(AbsSeekBar.java:837)
at com.kimso.sims.CustomSeekBar.onSizeChanged(jimsaSeekBar.java:242)
at com.kimso.sims.CustomSeekBar.setProgressInternally(jimsaSeekBar.java:435)
at com.kimso.sims.CustomSeekBar.setProgress(jimsaSeekBar.java:312)
at android.widget.ProgressBar.<init>(ProgressBar.java:376)
at android.widget.AbsSeekBar.<init>(AbsSeekBar.java:184)
at android.widget.SeekBar.<init>(SeekBar.java:89)
at android.widget.SeekBar.<init>(SeekBar.java:85)
at android.widget.SeekBar.<init>(SeekBar.java:81)
at com.kimso.sims.CustomSeekBar.<init>(jimsaSeekBar.java:82)
... 48 more

You are trying to set progress and call "onSizeChanged" at the same time in the constructor, before the view is attached to its parent and a window. That is not possible and you're getting a NullPointerException because of this issue. Try setting the progress on View.onAttachedToWindow() method by overriding it instead.
Edit: Well you can override the method in your CustomSeekBar if you just
write "onAttachedToWindow()" in the editor, just like you did at "onSizeChanged". Also you don't need to override "onSizeChanged", in fact that causes a wrong behavior in the code. Swapping width and height may not work there reliably.
Sample code would look like this I presume:
#Override
protected void onAttachedToWindow()
{
super.onAttachedToWindow();
// I believe you are trying to change the width-height depending on the orientation,
// so if the orientation is vertical you can swap the width and height.
// Remember this in the view though, so you wouldn't accidentally change it
// multiple times. Or, if you change it outside of the view lifecycle
// in the code, make sure to reset the state so you can put width-height
// properly again.
// This holds if the width-height change is applied.
// Define this as "private boolean layoutParametersChanged"
// at the top of the class.
if (!layoutParametersChanged)
{
// Mark as changed for the initial process.
layoutParametersChanged = true;
// I assume "1" stands for "Vertical" in your code.
// If it is horizontal, you shouldn't do a change.
if (mOrientation == 1)
{
// If you are using "wrap_content" or "match_parent" don't use them here.
// This check determines a fixed width and height, such as "60dp 60dp"
// for "layout_width" and "layout_height" parameters in the xml.
if (getLayoutParams().width > 0 && getLayoutParams().height > 0)
{
getLayoutParams().width = getHeight();
getLayoutParams().height = getWidth();
requestLayout();
}
else
{
// Wait for the layout to be attached, because if this is
// called, it's still not attached. To make sure, get
// width and height first. If they are non-zero, you can
// apply the change. Otherwise, attach a listener.
if (getWidth() > 0 && getHeight() > 0)
{
getLayoutParams().width = getHeight();
getLayoutParams().height = getWidth();
requestLayout();
}
else
{
// This will be called once the view dimensions are set,
// so you can safely use the width and height here.
getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
{
#Override
public boolean onPreDraw()
{
if (getViewTreeObserver().isAlive())
getViewTreeObserver().removeOnPreDrawListener(this);
getLayoutParams().width = getHeight();
getLayoutParams().height = getWidth();
requestLayout();
// Return true here.
return true;
}
});
}
}
}
}
}

It looks like you called init() so early which caused the NullPointerException eventually because your CustomSeekBar object isn't fully constructed. Remember that until the last line of your CustomSeekBar constructor, you cannot call any method such as setProgress() which will internally use the same object that is being created(as this is the case here).
Initially in the constructor you called init() > setProgress() > setProgressDetail() > setSeekBarChange() > setThumb() > updateThumbAndTrackPos() > setThumbPos() > updateGestureExclusionRects() > mGestureExclusionRects.clear() where mGestureExclusionRects is null because it isn't yet initialized.
Note: here ">" means "which in turn calls"
Instead, if you want to set the progress to 0 initially, then create a int variable initialized to 0 and then update it later from your xml to keep track of the progress in your CustomSeekBar view as :
public class CustomSeekBar extends AbsSeekBar {
private int mStartProgress;
public CustomSeekBar(Context context) {
this(context, null);
}
public CustomSeekBar(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.yourSeekBarStyle);
}
public CustomSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public CustomSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
// obtain attribute from xml and set it
final TypedArray a = ........;
mStartProgress = a.getInt(R.styleable.yourSeekBarStyle_startProgress, mStartProgress);
// ........
a.recycle();
}
private void init(){
// do not call method like setProgress() here
// as the object is still in the process of
// being created.
mStartProgress = 0;
}
}

Related

How to get Activity/getWindow() from services java class?

I'm trying to run a function that requires passing it a screen capture. When I run this from the main activity, I can run the code like this:
SendScreenFunction(getWindow().getDecorView().getRootView(), getApplicationContext());
I'm not trying to call this function from a service and I can't access the getWindow() function because it requires an activity (which isn't available in the service). I was looking around online and someone suggested a function to get the activity so I can use the function. My current code looks like this:
public class ASTasks extends Service {
// This method run only one time. At the first time of service created and running
#Override
public void onCreate() {
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
Log.d("onCreate()", "After service created");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Entered Timer!", Toast.LENGTH_SHORT).show();
Activity main_activity = getActivity(getApplicationContext());
try {
Log.i("Services", "Before crash");
SendScreenFunction(main_activity.getWindow().getDecorView().getRootView(), getApplicationContext());
Log.i("Services", "After crash");
} catch (IOException e) {
e.printStackTrace();
}
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding
return null;
}
public void SendScreenFunction(View view, Context context){
// Function goes here
}
public static Activity getActivity(Context context) {
if (context == null) return null;
if (context instanceof Activity) return (Activity) context;
if (context instanceof ContextWrapper) return getActivity(((ContextWrapper)context).getBaseContext());
return null;
}
}
Unfortunately, that solution doesn't seem to work and it's crashing. The Logcat error is shown below:
Process: com.example.ASservice:remote, PID: 15966
java.lang.RuntimeException: Unable to start service com.example.ASservice.ASTasks#6e7fed5 with Intent { cmp=com.example.ASservice/.ASTasks }: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window android.app.Activity.getWindow()' on a null object reference
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5110)
at android.app.ActivityThread.access$2100(ActivityThread.java:310)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2319)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8680)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window android.app.Activity.getWindow()' on a null object reference
at com.example.ASservice.ASTasks.onStartCommand(ASTasks.java:41)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5092)
at android.app.ActivityThread.access$2100(ActivityThread.java:310) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2319) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loopOnce(Looper.java:226) 
at android.os.Looper.loop(Looper.java:313) 
at android.app.ActivityThread.main(ActivityThread.java:8680) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135) 
Any ideas on the best way to take the screen capture from within the service (or even a way to pass a flag back to main to process it there)?
Any suggestions would be greatly appreciated. Thanks!

Android Game development E/JavaBinder: FAILED BINDER TRANSACTION

How to deal with E/JavaBinder: FAILED BINDER TRANSACTION that crashes the app?
I am making an android game using a SurfaceView.
I am also using a dedicated thread for the infinite Game-Loop itself, which contains both an update() method, as well as a draw() method.
The update() method updates characters position(logic) and sprites, while the draw() method draws to the canvas.
The dedicated thread handles both update() and draw() since they need to be synchronized.
The onTouchEvents (user clicks) are handled by the main thread.
Although I cannot tell for sure, I suspect that I am getting this error: E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! , because
both the draw() method and the update() method call other methods that call other methods and so on.. resulting in an almost a recursive behavior.
For example my update() method, calls characterOne.update().. which then calls characterOneSpells.update() which then calls spellOne.update() and so on... same thing for the draw(). I suspect that this overflows the bind buffer or something like that.. I am not sure.. and all of this is happening in an infinite loop infinite amount of times.
Note that I took this approach ( methods call methods that call other methods) because logically it made sense to me that a character should be responsible to draw itself, and a spell should be responsible to draw itself, rather than the character be responsible to draw and update the spells and so on. It made sense to me that every object should be responsible to draw itself and update itself, and that is my reasoning, I might be wrong, please let me know what you think.
Now, I am new to game making, and in fact this is my first game, so please take it easy on me, I am trying to learn!
Sample of my code and the error log can be found below.
Any insight to why I am getting this E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! and how to fix it would be very much appreciated! Also feel free to suggest a better design or approach, since I am trying to learn.
Thank you!
I marked the important parts of the code with ** Important ** comment to make things easier.`
ERROR LOG:
11-17 17:07:30.132 934-1460/? E/JavaBinder: !!! FAILED BINDER TRANSACTION !!!
11-17 17:07:30.388 1451-1451/? E/RecyclerView: No adapter attached; skipping layout
11-17 17:07:32.328 934-992/? E/InputDispatcher: channel '329e61e3 com.amazon.firelauncher/com.amazon.firelauncher.Launcher (server)' ~ Channel is unrecoverably broken and will be disposed!
11-17 17:07:32.407 146-146/? E/lowmemorykiller: Error opening /proc/2493/oom_score_adj; errno=2
11-17 17:07:32.442 934-1011/? E/WifiService: Multicaster binderDied
11-17 17:07:32.462 146-146/? E/lowmemorykiller: Error opening /proc/2493/oom_score_adj; errno=2
11-17 17:07:32.464 146-146/? E/lowmemorykiller: Error opening /proc/2493/oom_score_adj; errno=2
11-17 17:07:32.464 146-146/? E/lowmemorykiller: Error opening /proc/1217/oom_score_adj; errno=2
11-17 17:07:36.426 6868-6868/? E/cr_AWVDeploymentClient: Chromium Version = v59 key doesn't exist. So, default version config will be used.
11-17 17:07:36.428 6868-6868/? E/cr_AWVDeploymentClient: Default device config doesn't exist
11-17 17:07:39.313 934-992/? E/InputDispatcher: channel '11e88fc0 info.evyatar.mystrategygame/info.evyatar.mystrategygame.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
11-17 17:07:40.905 7010-7051/? E/SQLiteLog: (283) recovered 44 frames from WAL file /data/user/0/com.amazon.firelauncher/databases/producer.db-wal
11-17 17:07:41.091 7010-7059/? E/SQLiteLog: (283) recovered 90 frames from WAL file /data/user/0/com.amazon.firelauncher/databases/CardDeviceAgentDB-wal
11-17 17:07:43.558 7010-7010/? E/RecyclerView: No adapter attached; skipping layout
11-17 17:07:43.622 7089-7089/? E/TimeoutManagerClient: bindService() Failed to bind to ECService
11-17 17:07:43.631 7165-7165/? E/Dagger2: ApplicationModule context already set
11-17 17:07:44.924 7089-7311/? E/...iceDataCommunication: Got a RemoteMAPException
com.amazon.identity.auth.device.framework.RemoteMAPException: com.amazon.identity.auth.device.api.DeviceDataStoreException: Key ke_device was not found in the device data store. This device does not support ke_device. This error is expected if the device not support ke_device.
at com.amazon.identity.auth.device.framework.SecureContentResolver.acquireContentProviderClient(SecureContentResolver.java:118)
at com.amazon.identity.auth.device.devicedata.DeviceDataCommunication.retriveValueFromCentralStore(DeviceDataCommunication.java:59)
at com.amazon.identity.auth.device.devicedata.DeviceDataCommunication.getValue(DeviceDataCommunication.java:52)
at com.amazon.identity.auth.device.devicedata.DeviceDataStoreSystemPropertyDecorator.getValue(DeviceDataStoreSystemPropertyDecorator.java:52)
at com.amazon.identity.auth.device.api.DeviceDataStore.getValue(DeviceDataStore.java:96)
at com.amazon.avod.identity.DeviceProperties.isKidsEditionDevice(DeviceProperties.java:374)
at com.amazon.avod.identity.DeviceProperties.initialize(DeviceProperties.java:201)
at com.amazon.avod.core.ApplicationComponents$InitializeDeviceProperties.initialize(ApplicationComponents.java:543)
at com.amazon.avod.core.ApplicationComponents$InitializeRunnable.run(ApplicationComponents.java:787)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: com.amazon.identity.auth.device.api.DeviceDataStoreException: Key ke_device was not found in the device data store. This device does not support ke_device. This error is expected if the device not support ke_device.
at com.amazon.identity.auth.device.devicedata.DeviceDataCommunication$1.useContentProviderClient(DeviceDataCommunication.java:93)
at com.amazon.identity.auth.device.devicedata.DeviceDataCommunication$1.useContentProviderClient(DeviceDataCommunication.java:61)
at com.amazon.identity.auth.device.framework.SecureContentResolver.acquireContentProviderClient(SecureContentResolver.java:112)
at com.amazon.identity.auth.device.devicedata.DeviceDataCommunication.retriveValueFromCentralStore(DeviceDataCommunication.java:59) 
at com.amazon.identity.auth.device.devicedata.DeviceDataCommunication.getValue(DeviceDataCommunication.java:52) 
at com.amazon.identity.auth.device.devicedata.DeviceDataStoreSystemPropertyDecorator.getValue(DeviceDataStoreSystemPropertyDecorator.java:52) 
at com.amazon.identity.auth.device.api.DeviceDataStore.getValue(DeviceDataStore.java:96) 
at com.amazon.avod.identity.DeviceProperties.isKidsEditionDevice(DeviceProperties.java:374) 
at com.amazon.avod.identity.DeviceProperties.initialize(DeviceProperties.java:201) 
at com.amazon.avod.core.ApplicationComponents$InitializeDeviceProperties.initialize(ApplicationComponents.java:543) 
at com.amazon.avod.core.ApplicationComponents$InitializeRunnable.run(ApplicationComponents.java:787) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
at java.lang.Thread.run(Thread.java:818) 
11-17 17:07:45.701 7010-7085/? E/...iceDataCommunication: Got a RemoteMAPException
com.amazon.identity.auth.device.framework.RemoteMAPException: com.amazon.identity.auth.device.api.DeviceDataStoreException: Key re_device was not found in the device data store. This device does not support re_device. This error is expected if the device not support re_device.
at com.amazon.identity.auth.device.framework.SecureContentResolver.acquireContentProviderClient(SecureContentResolver.java:118)
at com.amazon.identity.auth.device.devicedata.DeviceDataCommunication.retriveValueFromCentralStore(DeviceDataCommunication.java:59)
at com.amazon.identity.auth.device.devicedata.DeviceDataCommunication.getValue(DeviceDataCommunication.java:52
at java.lang.Thread.run(Thread.java:818)
Caused by: com.amazon.identity.auth.device.api.DeviceDataStoreException: Key re_device was not found in the device data store. This device does not support re_device. This error is expected if the device not support re_device.
at com.amazon.identity.auth.device.devicedata.DeviceDataCommunication$1.useContentProviderClient(DeviceDataCommunication.java:93)
at com.amazon.identity.auth.device.devicedata.DeviceDataCommunication$1.useContentProviderClient(DeviceDataCommunication.java:61)
at com.amazon.firelauncher.services.MapCache.updateDeviceData(MapCache.java:579) 
at com.amazon.firelauncher.services.MapCache.access$700(MapCache.java:47) 
at com.amazon.firelauncher.services.MapCache$3.run(MapCache.java:491) 
at com.amazon.firelauncher.services.BackgroundExecutor$InternalRunnable.run(BackgroundExecutor.java:180) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
at java.lang.Thread.run(Thread.java:818) 
11-17 17:07:45.930 7343-7343/? E/SQLiteLog: (283) recovered 120 frames from WAL file /data/securedStorageLocation/com.amazon.providers.contentsupport/contentsupport.db-wal
11-17 17:07:45.979 7343-7343/? E/SQLiteLog: (284) automatic index on languages(packageId)
11-17 17:07:46.007 7343-7343/? E/SQLiteLog: (284) automatic index on languages(packageId)
11-17 17:07:47.386 7010-7417/? E/F_C.ArcusRemoteConfigur: No valid offline remote setting found for the current device, not setting default
java.lang.Exception: Error getting the baseline setting for Arcus config cms
at com.amazon.firelauncher.reccardproducer.settings.OfflineSetting.value(OfflineSetting.java:106)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: java.lang.Exception: Exception reading from cms/baseline.json
at com.amazon.firelauncher.reccardproducer.settings.JSONFile.value(JSONFile.java:43)
at com.amazon.firelauncher.reccardproducer.settings.JSONFile.value(JSONFile.java:14)
at com.amazon.firelauncher.reccardproducer.settings.OfflineSetting.value(OfflineSetting.java:88)
at com.amazon.firelauncher.reccardproducer.settings.OfflineSetting.value(OfflineSetting.java:22) 
at com.amazon.firelauncher.reccardproducer.arcus.ArcusRemoteConfiguration$1.map(ArcusRemoteConfiguration.java:67) 
at com.amazon.firelauncher.reccardproducer.arcus.ArcusRemoteConfiguration$1.map(ArcusRemoteConfiguration.java:60) 
at com.amazon.firelauncher.reccardproducer.arcus.ArcusRemoteConfiguration.initialize(ArcusRemoteConfiguration.java:117) 
at com.amazon.firelauncher.reccardproducer.cards.RecommendationsController.getInstance(RecommendationsController.java:111) 
at com.amazon.firelauncher.reccardproducer.ProducerService.onHandleIntent(ProducerService.java:57) 
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.os.HandlerThread.run(HandlerThread.java:61) 
Caused by: java.io.FileNotFoundException: cms/baseline.json
at android.content.res.AssetManager.openAsset(Native Method)
at android.content.res.AssetManager.open(AssetManager.java:313)
at android.content.res.AssetManager.open(AssetManager.java:287)
at com.amazon.firelauncher.reccardproducer.settings.JSONFile.value(JSONFile.java:29)
at com.amazon.firelauncher.reccardproducer.settings.JSONFile.value(JSONFile.java:14) 
at com.amazon.firelauncher.reccardproducer.settings.OfflineSetting.value(OfflineSetting.java:88) 
at com.amazon.firelauncher.reccardproducer.cards.RecommendationsController.getInstance(RecommendationsController.java:111) 
at com.amazon.firelauncher.reccardproducer.ProducerService.onHandleIntent(ProducerService.java:57) 
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.os.HandlerThread.run(HandlerThread.java:61) 
11-17 17:07:47.400 7010-7417/? E/F_C.FireDeviceAttribute: BuildNumber is not a valid String attribute (wrong type: Integer)
11-17 17:07:47.416 7010-7417/? E/F_C.ArcusParameters: Exception getting attribute %s, no attribute added
java.lang.NullPointerException: attrValue cannot be null
at com.amazonaws.mobileconnectors.remoteconfiguration.internal.gear.Checks.checkNotNull(Checks.java:20)
at com.amazonaws.mobileconnectors.remoteconfiguration.internal.AttributesImpl.addAttributePrivate(AttributesImpl.java:193)
at com.amazonaws.mobileconnectors.remoteconfiguration.internal.AttributesImpl.addAttribute(AttributesImpl.java:103)
at com.amazon.firelauncher.reccardproducer.arcus.ArcusParameters.decorateManager(ArcusParameters.java:87)
at com.amazon.firelauncher.reccardproducer.arcus.ArcusRemoteConfiguration.initialize(ArcusRemoteConfiguration.java:119)
at com.amazon.firelauncher.reccardproducer.cards.RecommendationsController.getInstance(RecommendationsController.java:111)
at com.amazon.firelauncher.reccardproducer.ProducerService.onHandleIntent(ProducerService.java:57)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
Sample Code
public class GameLoop extends SurfaceView implements SurfaceHolder.Callback {
private Context myContext;
private SurfaceHolder mySurfaceHolder;
private Bitmap backgroundImg;
private int screenW = 1;
private int screenH = 1;
private boolean running = false;
private boolean onTitleScreen = true;
private GameLoopThread thread;
private int backgroundOrigW;
private int backgroundOrigH;
private float scaleW;
private float scaleH;
private float drawScaleW;
private float drawScaleH;
private int fingerX, fingerY;
private boolean isDragging = false;
SingltonAssetsObject mSingltonAssetsObject;
private boolean gameOver;
Point userClickPoint;
//Characters
CharacterTypeOne characterFighterOne,characterFighterTwo,characterFighterThree;
CharacterTypeTwo CharacterMage;
public GameLoop(Context context, AttributeSet attrs) {
super(context, attrs);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
//init clickRectangle
userClickPoint = new Point();
//creates the gameLoop thread DRAW THREAD
thread = new GameLoopThread(holder,context);
setFocusable(true);
}
public void initCharacters(){
mSingltonAssetsObject = SingltonAssetsObject.getInstance(myContext,scaleW,scaleH);
characterFighterOne = new characterFighterOne(myContext,1000,1,150,350,100,15,1.0,scaleW,scaleH,drawScaleW,drawScaleH,screenW,screenH);
characterFighterTwo = new characterFighterOne(myContext,1001,67,350,350,100,15,1.0,scaleW,scaleH,drawScaleW,drawScaleH,screenW,screenH);
characterFighterThree = new characterFighterOne(myContext,1002,99,550,350,1000,15,1.0,scaleW,scaleH,drawScaleW,drawScaleH,screenW,screenH);
characterMage = new characterMage(myContext,50,28,650,250,100,15,0.1,scaleW,scaleH,drawScaleW,drawScaleH,screenW,screenH);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return thread.doTouchEvent(event);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
thread.setSurfaceSize(width, height);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
if (thread.getState() == Thread.State.NEW) {
thread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
thread.setRunning(false);
}
class GameLoopThread extends Thread{
public GameLoopThread(SurfaceHolder surfaceHolder, Context context){
//initialzied in inner class and not outter because this variable will act as a lock and will be shard with all threads
mySurfaceHolder = surfaceHolder;
myContext = context;
//the background image of the title screen
backgroundImg = BitmapFactory.decodeResource(context.getResources(), R.drawable.title);
backgroundOrigW = backgroundImg.getWidth();
backgroundOrigH = backgroundImg.getHeight();
}
//This method is the main game loop
public void run() {
while (running) {
try { //lock canvas for drawing
c = mySurfaceHolder.lockCanvas(null);
synchronized (mySurfaceHolder) {
if (!gameOver)
{
//** important ***
updateAnimationsAndPosition();
}
// **important **
draw(c);
}
} finally {
if (c != null) { //unlock canvas
mySurfaceHolder.unlockCanvasAndPost(c);
}
}
} //while loop ends
} //run Method ends (gameLOOP)
//This method will draw everything to the screen
public void draw(Canvas canvas){
canvas.drawBitmap(backgroundImg, 0, 0, null);
if (!onTitleScreen) {
/* **Important**
Note: characterFighterOne.draw(canvas) calls spells.draw(canvas)
which calls spellOne.draw(canvas).. which call spellIndicartor.draw(canvas)
and so on... might be cauing the isssue?*/
characterFighterOne.draw(canvas);
characterFighterTwo.draw(canvas);
characterFighterThree.draw(canvas);
characterMage.draw(canvas);
}
}
//This method updates the animations, for example changes image every tick
public void updateAnimationsAndPosition(){
if(!onTitleScreen){
/***Important**
Note: characterFighterOne.updateAnimationsAndPosition() calls spells.update()
which calls spellOne.update().. which call spellIndicartor.update()
and so on... might be causing the issue?*/
characterFighterOne.updateAnimationsAndPosition();
characterFighterTwo.updateAnimationsAndPosition();
characterFighterThree.updateAnimationsAndPosition();
characterMage.updateAnimationsAndPosition();
}
}
public void setSurfaceSize(int width, int height) {
synchronized (mySurfaceHolder) {
screenW = width;
screenH = height;
backgroundImg = Bitmap.createScaledBitmap(backgroundImg, width, height, true);
drawScaleW = (float) screenW / 960; //screen/background width image
drawScaleH = (float) screenH / 640;
}
}
//This method is in charge of user input ( clicks on screen, and how to respond to them)
public boolean doTouchEvent(MotionEvent event){
if(!onTitleScreen){
characterFighterOne.doTouchEvent(event);
characterFighterTwo.doTouchEvent(event);
characterFighterThree.doTouchEvent(event);
characterMage.doTouchEvent(event);
userClickPoint.set((int)event.getX(),(int)event.getY());
}
synchronized (mySurfaceHolder) {
int eventaction = event.getAction();
int X = (int)event.getX();
int Y = (int)event.getY();
switch (eventaction ) {
case MotionEvent.ACTION_DOWN:
if(!gameOver){
fingerX = X;
fingerY = Y;
if (!onTitleScreen) {
}
}
break;
case MotionEvent.ACTION_MOVE:// used for dragging purposes
break;
case MotionEvent.ACTION_UP:
//Here I load all the images to memory ( while on the titleScreen normal size & scaled, find a better place, maybe OnCreate, leave for now)
if (onTitleScreen) {
backgroundImg = BitmapFactory.decodeResource(myContext.getResources(), R.drawable.background);
backgroundImg = Bitmap.createScaledBitmap(backgroundImg, screenW, screenH, true);
onTitleScreen = false;
scaleW = (float) screenW/ (float) backgroundOrigW;
scaleH = (float) screenH/ (float) backgroundOrigH;
initCharacters();
}
if (gameOver) {
gameOver = false;
}
break;
}
}
return true;
}
//This method enables and disables the Thread
public void setRunning(boolean b) {
running = b;
}
}
}

SimpleCursorAdapter issue - "java.lang.IllegalStateException: trying to requery an already closed cursor"

I've read similar topics and didn't find any answer that I could apply to my situation.
Long story short, I have an AutoCompleteTextView with SimpleCursorAdapter. It queries my SQLiteDatabase for the matching drop down list of options.
Everything works fine, but when I press the "Home" button (onPause() -> onStop()) if I've shortly before that used the AutoCompleteTextView, upon re-entering the app (onRestart() -> onStart() -> onResume()), I get this error:
03-05 19:17:42.186 13847-13847/com.ardovic.weatherappprototype
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ardovic.weatherappprototype, PID: 13847
java.lang.RuntimeException: Unable to resume activity
{com.ardovic.weatherappprototype/com.ardovic.weatherappprototype.MainActivity}:
java.lang.IllegalStateException: trying to requery an already closed
cursor android.database.sqlite.SQLiteCursor#2cae0855
at
android.app.ActivityThread.performResumeActivity(ActivityThread.java:4053)
at
android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4084)
at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1749)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6918)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Caused by: java.lang.IllegalStateException: trying to requery an
already closed cursor android.database.sqlite.SQLiteCursor#2cae0855
at android.app.Activity.performRestart(Activity.java:6660)
at android.app.Activity.performResume(Activity.java:6688)
at
android.app.ActivityThread.performResumeActivity(ActivityThread.java:4042)
at
android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4084) 
at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1749) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:145) 
at android.app.ActivityThread.main(ActivityThread.java:6918) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
It doesn't point to any of my code lines, so I suppose that it's the SimpleCursorAdapter problem. Here is the code for it (I've commented out unrelated parts, but they are still there):
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.dropdown_text,
null,
new String[]{CITY_COUNTRY_NAME},
new int[]{R.id.text});
actvCityCountryName.setAdapter(adapter);
actvCityCountryName.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> listView, View view, int position, long id) {
cursor = (Cursor) listView.getItemAtPosition(position);
// cityCountryName = cursor.getString(cursor.getColumnIndexOrThrow(CITY_COUNTRY_NAME));
// actvCityCountryName.setText(cityCountryName);
// JSONWeatherTask task = new JSONWeatherTask();
// task.execute(new String[]{cityCountryName});
}
});
adapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
#Override
public CharSequence convertToString(Cursor cursor) {
final int columnIndex = cursor.getColumnIndexOrThrow(CITY_COUNTRY_NAME);
final String cityCountryName = cursor.getString(columnIndex);
return (cityCountryName);
}
});
adapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
// cursor = getMatchingStates((constraint != null ? constraint.toString() : null));
return cursor;
}
});
I've already tried various suggestions, like calling stopManagingCursor(cursor), cursor.requery(), actvCityCountryName.dismissDropDown(), actvCityCountryName.clearListSelection(), or actvCityCountryName.clearFocus() in various places and lifecycle methods.
Looking forward for any suggestions that would solve this problem, thanx in advance!

Why does my Activity get destroyed upon adding a fragment (#2)?

I want to make it clear that this question will look very similar to one I asked earlier, but that I'm not asking exactly the same thing.
In my previous question, I got a RuntimeException/IllegalStateException, which told me my Activity got destroyed upon adding a new fragment.
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tim.timapp
/com.example.tim.timapp.MainActivity}: java.lang.IllegalStateException:
Activity has been destroyed
In that case, it turned out it had to do with me creating new instances of MainActivityin an invalid way:
MainActivity ma = new MainActivity();
(PSA: Don't do the above, use MainActivity ma = (MainActivity) getActivity(); instead.)
I have now corrected this in my entire project, and am getting almost exactly the same error. Let me be clear: I (think I) know the original error was fixed, because I got a different error in between these two RE's, which I was able to fix myself.
To reiterate on my gibberish: Got the first RE, fixed it with the answer on my question, got a different error, fixed that myself, got almost exactly the same RE.
I have searched through my entire project to see if I had anything similar to the error I made before, but I can't find anything, so here I am. So basically, the answer I got on my previous question fixed my issue, temporarily. That answer however, does not help me with this new error I'm getting, that's why I'm asking this question.
TL;DR: Answer on Q1 fixed my issue at first(which makes it a working answer), but it does not fix the issue I'm having right now, which is almost the same.
The actual question
So, now we've got that bit out of the way, let's get on with my issue. So, I'm getting a RuntimeException/IllegalStateExcetion:
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example.tim.timapp/com.example.tim.timapp.MainActivity}:
java.lang.IllegalStateException: Activity has been destroyed
(PS. It's only a RE because I have my app navigate to the GeneralSettings fragment on startup, for debugging ease.)
I've read up on this kind of error, but nothing I could find that applies on my project.
So, what is causing this RuntimeException/IllegalStateException?
Full log
04-05 14:17:53.140 23411-23411/? I/art: Not late-enabling -Xcheck:jni (already on)
04-05 14:17:53.190 23411-23411/com.example.tim.timapp W/System: ClassLoader referenced unknown path: /data/app/com.example.tim.timapp-1/lib/x86_64
04-05 14:17:53.210 23411-23411/com.example.tim.timapp D/TEST DBHandler: sInstance == null
04-05 14:17:53.370 23411-23411/com.example.tim.timapp D/AndroidRuntime: Shutting down VM
04-05 14:17:53.370 23411-23411/com.example.tim.timapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.tim.timapp, PID: 23411
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tim.timapp/com.example.tim.timapp.MainActivity}: java.lang.IllegalStateException: Activity has been destroyed
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.IllegalStateException: Activity has been destroyed
at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1433)
at android.app.BackStackRecord.commitInternal(BackStackRecord.java:687)
at android.app.BackStackRecord.commit(BackStackRecord.java:663)
at com.example.tim.timapp.MainActivity.DrawVariableFragments(MainActivity.java:276)
at com.example.fragments.Settings.GeneralSettingsFragment.onCreateView(GeneralSettingsFragment.java:58)
at android.app.Fragment.performCreateView(Fragment.java:2220)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:973)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
at android.app.BackStackRecord.run(BackStackRecord.java:793)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
at android.app.FragmentController.execPendingActions(FragmentController.java:325)
at android.app.Activity.performStart(Activity.java:6252)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
MainActivity (Snippet)
package com.example.tim.timapp;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private static boolean isMainShown = false;
private static boolean isSettingsShown = false;
private static boolean doSavePopup = false;
private static String backTitle = "";
private String tag = "TEST MA";
DBHandler dbHandler;
Menu menu;
public void DrawVariableFragments(String base,String token){
// FragmentManager fm = getFragmentManager();
ArrayList<String> Data;
dbHandler = DBHandler.getInstance(this);
int AmountOfEntries;
int SettingsContainer;
String SettingsTag;
Fragment SettingsVariableFragment;
Fragment SettingsEmptyFragment;
if (base.equalsIgnoreCase("StuffManager")) {
Data = new ArrayList<String>() {{add("StuffManager"); add("name"); add("tag"); }};
SettingsContainer = R.id.FragmentContainer2;
SettingsTag = getString(R.string.navdrawer_stuffmanager);
SettingsVariableFragment = new StuffManagerVariableFragment();
SettingsEmptyFragment = new StuffManagerEmptyFragment();
} else if (base.equalsIgnoreCase("GeneralSettings")) {
Data = new ArrayList<String>() {{add("GeneralSettings"); add("name"); add("ip"); add("port"); add("username"); add("pass"); }};
SettingsContainer = R.id.FragmentContainerGeneralSettings;
SettingsTag = getString(R.string.navdrawer_generalsettings);
SettingsVariableFragment = new GeneralSettingsVariableFragment();
SettingsEmptyFragment = new GeneralSettingsEmptyFragment();
} else {
Log.e(tag, "String Base not recognised");
return;
}
AmountOfEntries = dbHandler.returnArray(base, Data.get(1)).size();
FragmentManager fm = getFragmentManager().findFragmentByTag(SettingsTag).getChildFragmentManager();
if ((dbHandler.returnArray(base, Data.get(1))).size() == 0 ) {
// Log.d(tag, "SettingsContainer1: " + String.valueOf(SettingsContainer) + "; SettingsEmtpyFragment1: " + SettingsEmptyFragment + "; Base1: " + base);
fm.beginTransaction().add(SettingsContainer, SettingsEmptyFragment, (base + "EmptyFragment")).commit();
fm.executePendingTransactions();
return;
}
if (AmountOfEntries > 0) {
String EmptyFragName = (base + "EmptyFragment");
if ((fm.findFragmentByTag(EmptyFragName)) != null) {
fm.beginTransaction().remove(fm.findFragmentByTag(EmptyFragName)).commit();
fm.executePendingTransactions();
}
for (int i = 0; i < AmountOfEntries; i++) {
ArrayList<String> fragmentData = new ArrayList<>();
for (int k=1; k < Data.size(); k++) {
int j=k-1;
fragmentData.set(j, (dbHandler.returnArray(base, Data.get(k)).get(j)));
}
if (token.equalsIgnoreCase("edit")) {
LinearLayout linearLayout = (LinearLayout) findViewById(SettingsContainer);
linearLayout.removeAllViews();
DrawVariableFragments(base ,"draw");
} else if (token.equalsIgnoreCase("add")) {
if (fm.findFragmentByTag(fragmentData.get(i)) == null) {
fm.beginTransaction().add(SettingsContainer, SettingsVariableFragment, fragmentData.get(0)).commit();
fm.executePendingTransactions();
if (base.equalsIgnoreCase("StuffManager")) {
((StuffManagerVariableFragment) fm
.findFragmentByTag(fragmentData.get(i)))
.setText(fragmentData.get(0), fragmentData.get(1));
} else if (base.equalsIgnoreCase("GeneralSettings")) {
((GeneralSettingsVariableFragment) fm
.findFragmentByTag(fragmentData.get(i)))
.setText(fragmentData.get(0), fragmentData.get(1), fragmentData.get(2), fragmentData.get(3));
}
}
} else if (token.equalsIgnoreCase("draw")) {
fm.beginTransaction().add(SettingsContainer, SettingsVariableFragment, fragmentData.get(0)).commit();
fm.executePendingTransactions();
if (base.equalsIgnoreCase("StuffManager")) {
((StuffManagerVariableFragment) fm
.findFragmentByTag(fragmentData.get(i)))
.setText(fragmentData.get(0), fragmentData.get(1));
} else if (base.equalsIgnoreCase("GeneralSettings")) {
((GeneralSettingsVariableFragment) fm
.findFragmentByTag(fragmentData.get(i)))
.setText(fragmentData.get(0), fragmentData.get(1), fragmentData.get(2), fragmentData.get(3));
}
}
}
} else {
Log.d("TEST", "WTF, nameArray.size != 0 && !> 0");
}
}
}
GeneralSettingsFragment (Snippet)
package com.example.fragments.Settings;
public class GeneralSettingsFragment extends Fragment {
MainActivity ma;
DBHandler dbHandler;
private static Menu optionsMenu;
public static boolean hideDeleteAllButton = false;
LinearLayout linearLayout;
View rootView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_generalsettings, container, false);
ma = (MainActivity) getActivity();
linearLayout = (LinearLayout) rootView.findViewById(R.id.FragmentContainerGeneralSettings);
if (linearLayout == null) {
Log.e("GMF", "Layout is null");
} else if (linearLayout.getChildCount() == 0) {
GeneralSettingsInitialInputDialog GSIID = new GeneralSettingsInitialInputDialog();
GSIID.show(getFragmentManager(), "dialog");
hideDeleteAllButton = true;
} else {
hideDeleteAllButton = false;
}
ma.DrawVariableFragments("GeneralSettings", "draw");
return rootView;
}
}
You are still doing things in an unsupported way. In MainActivity.DrawVariableFragments() you are creating a new GeneralSettingsVariableFragment() and then call getChildFragmentManager() on it and attempt to commit a fragment.
The GeneralSettingsFragment has not yet been attached to an Activity so it does not have a host. This throws the IllegalStateException("Activity has been destroyed") exception you are seeing when you try to commit the FragmentTransaction.
It is unclear why you are creating a new GeneralSettingsVariableFragmentwhen you are already inside a new instance of one.
To properly lookup an existing fragment use getFragmentManager().findFragmentByTag(...) or getFragmentManager().findFragmentById(...).

Can't save state of RelativeLayout

I am making an application which has an activity where the user can add a picture to an object, here I give the user the choice between selecting a picture from the gallery or making a new one using the camera. Both of these options start an Intent which (after the user is done choosing a picture) returns to activity it came from.
But the problem I'm having is that when the user comes back sometimes some of the data of that activity is lost, so I "reload" it using a savedInstance. One of the objects I try to save is an arraylist of custom views that extend RelativeLayout. But when I load the data the following I get the following error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sition.projectmanager/com.example.sition.projectmanager.activities.ObjectActivity}: java.lang.RuntimeException: Parcelable encountered IOException reading a Serializable object (name = com.example.sition.projectmanager.TabButton)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2262)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316)
at android.app.ActivityThread.access$700(ActivityThread.java:158)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5365)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Parcelable encountered IOException reading a Serializable object (name = com.example.sition.projectmanager.TabButton)
at android.os.Parcel.readSerializable(Parcel.java:2144)
at android.os.Parcel.readValue(Parcel.java:2016)
at android.os.Parcel.readListInternal(Parcel.java:2235)
at android.os.Parcel.readArrayList(Parcel.java:1655)
at android.os.Parcel.readValue(Parcel.java:1986)
at android.os.Parcel.readMapInternal(Parcel.java:2226)
at android.os.Bundle.unparcel(Bundle.java:223)
at android.os.Bundle.getParcelable(Bundle.java:1173)
at android.app.Activity.onCreate(Activity.java:930)
at com.example.sition.projectmanager.activities.ObjectActivity.onCreate(ObjectActivity.java:102)
at android.app.Activity.performCreate(Activity.java:5326)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2225)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316) 
at android.app.ActivityThread.access$700(ActivityThread.java:158) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:176) 
at android.app.ActivityThread.main(ActivityThread.java:5365) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:511) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 
at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.io.InvalidClassException: android.widget.RelativeLayout; IllegalAccessException
at java.io.ObjectStreamClass.resolveConstructorClass(ObjectStreamClass.java:692)
at java.io.ObjectStreamClass.newInstance(ObjectStreamClass.java:653)
at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1826)
at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:787)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2013)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1970)
at android.os.Parcel.readSerializable(Parcel.java:2142)
at android.os.Parcel.readValue(Parcel.java:2016) 
at android.os.Parcel.readListInternal(Parcel.java:2235) 
at android.os.Parcel.readArrayList(Parcel.java:1655) 
at android.os.Parcel.readValue(Parcel.java:1986) 
at android.os.Parcel.readMapInternal(Parcel.java:2226) 
at android.os.Bundle.unparcel(Bundle.java:223) 
at android.os.Bundle.getParcelable(Bundle.java:1173) 
at android.app.Activity.onCreate(Activity.java:930) 
at com.example.sition.projectmanager.activities.ObjectActivity.onCreate(ObjectActivity.java:102) 
at android.app.Activity.performCreate(Activity.java:5326) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2225) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316) 
at android.app.ActivityThread.access$700(ActivityThread.java:158) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:176) 
at android.app.ActivityThread.main(ActivityThread.java:5365) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:511) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 
at dalvik.system.NativeStart.main(Native Method) 
Here is my custom RelativeLayout Class:
public class TabButton extends RelativeLayout implements Serializable {
public TabButton(Context context) {
super(context);
}
public TabButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TabButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
And my onSaveInstanceState and onRestoreInstanceState:
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putSerializable("CURRENT_OBJECT",currentObject);
outState.putSerializable("TAB_BUTTONS", tabButtons);
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
currentObject = (Objectable) savedInstanceState.getSerializable("CURRENT_OBJECT");
tabButtons = (ArrayList<TabButton>) savedInstanceState.getSerializable("TAB_BUTTONS");
}
What am I doing wrong?
Your concept is wrong: You should not save entire widgets, but the information to recreate them.
However, your activity might have more state information that you'd
like to restore, such as member variables that track the user's
progress in the activity.
from: Android Activity Lifecycle, Android SDK Docs
So save information as ints (in your example for identifying the selected tab) or other primitives and set in onRestoreInstanceState.

Categories