Android - general settings set in AsyncTask onPostExecute () not always set?

I have code that works 98% of the time and 100% during my own testing, so I cannot reproduce a problem other than how user devices experience this problem.

What I do in onPostExecute () is setting this parameter:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( AddProblemActivity.this); prefs.edit().putString("recent_problem_id", result ).commit(); 

and then go to the next step:

  Intent myIntent = new Intent(AddProblemActivity.this, ProblemActivity.class); AddProblemActivity.this.startActivity(myIntent); 

and then try to find this parameter as follows:

 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( ProblemActivity.this); // display a loading message before problem loads. String recent_problem_id = prefs.getString( "recent_problem_id" , null ); if ( recent_problem_id == null ) { // Sometimes it is null! } 

Does anyone know why this is happening?

Thanks!

+4
source share
7 answers

If you are trying to pass data into a new action, why not put it as a string in an intent? Then get this line from the intent in the new action. If you still need to save it, you can do it in the new onCreate () action after it pulls it out of intent.

 Intent myIntent = new Intent(AddProblemActivity.this, ProblemActivity.class); //Add results here myIntent.putExtra("RecentProblemId", result); AddProblemActivity.this.startActivity(myIntent); 

Then in onCreate of your new action do:

 String recentProblemId = getIntent().getStringExtra("RecentProblemId"); 

Now, if you still need this information, follow these steps:

 if(recentProblemId != null){ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( ProblemActivity.this); prefs.putString("recent_problem_id",recentProblemId).commit(); } 

I know this does not exactly answer your question about why String is not always bound to preferences in onPostExecute (). However, the best practice of transferring information between events is intentions and complementary services.

My guess about why this may not always work for some users is that their devices do not write data to the general settings file before starting a new action and try to read from the same file. Hope this helps.

+5
source

First of all, see the answer of Raghava Saud.
There is one delicate point. You can start to execute your AsyncTask, than to rotate the device. The activity will be recreated, and in PostExecute you will have the wrong context so that your settings are not saved.
If true, you should use onRetainNonConfigurationInstance () to save the corresponding instance of the task.

+2
source

I am not sure about this, but I think the problem may be due to the difference in the Context that you are passing. First you use the AddProblemActivity context, and then the ProblemActivity context. Try using your preference, for example, the file name:

 SharedPreferences prefs = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE); 

Note that getSharedPreferences () is a method from the context, so you will need to have a reference to the Activity, or perhaps the application context in your AsyncTask will be able to use it.

+1
source

It seems that your code is in order, and there is no reason why it should not work, the only reason could be some defect, which is probably related to the device. My thoughts are related to the fact that common prefs are stored in local storage. In this process, something may go wrong.

As indicated in the comments, you need to add a device type log. I would recommend you use "ACRA" - http://code.google.com/p/acra/ , which can give you detailed reports with minimal effort (note that you You can send a report not only if the application crashes).

Take a look at this topic, it shows the problem you are probably experiencing: SharedPreferences will not save / load in PreferenceActivity . In this case, the solution will be to manually save this persistent data in local storage or use a database solution. Good luck :)

+1
source

I think the problem is that the general preference setting is not written to your file system, but when you try to access it from your second action. You mentioned that you are writing a parameter from the onPostExecute method ( AsyncTask , maybe?). When starting AsyncTask there is no guarantee that it will start immediately. The only guarantee is that it will start in the background thread. The platform can and will decide when to actually start the background thread, depending on the system load, file system blocks, or so on. It is possible that your AsyncTask is not already running when you switch to the second action (and therefore the onPostExecute method has not yet been called).

Saving general settings is difficult because they are written to the file system. If you are not careful, you can block the main thread. The SharedPreferences.Editor object has an apply method that will immediately update the memory cache in your general preferences (making the changes available immediately) and hit the background thread to keep the actual value in the file system as Well. Therefore, my advice will be that if you have such an opportunity, you should try to call the apply method (from the main thread) instead of the commit method from (what I assume) a AsyncTask . The apply method requires API level 9 or higher.

For reference: http://developer.android.com/reference/android/content/SharedPreferences.Editor.html

Edit:

The commit method returns a boolean based on the result of a write operation. You could (should?) Check this return value to at least be able to take the right counter measures in the event of a failure (for example, show "Failed to save settings, try again", toast or something else).

Cheers, --dbm

+1
source

I could be wrong. But I believe that my friend had a similar problem. I am stuck with this problem for hours. Results in more than 30% of cases will not work. I believe that onPostExecute () works in a separate thread when an Intent instance is created and the action is called. This is because AsyncTask is implemented in a separate thread. Depending on the device, this will be more likely and then not. Our tablet rarely happened, on a smartphone it happened more often.

You can test this by debugging the application and looking at the AsyncThread thread and see when the call is made.

Yes, it’s better to send the variable via putExtra ().

Hope this helps you understand why this happened.

0
source

The commit action for SharePreferences is synchronized, so I don’t think that the fact that you are starting a new intention should fix it, only the fact that the commit action is not safe, it can fail.

http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#commit ()

Returns true if new values ​​were successfully written to persistent storage.

Perhaps you should check this return value to make sure you manage to save the result.

0
source

Source: https://habr.com/ru/post/1436396/


All Articles