submitScoreGPGS does not work with AsyncTask - android

I am trying to get the Google Play Services working as following using AsyncTaks:
1 - The Login Dialog is only displayed when the user click on the leaderboard button which call the method loginGPRS() below;
2 - An ansync task is then executed which call the startLoginGRPS() method on the onPreExecute
3 - [Here is the problem] Once he is logged in, I want to call the methods submitScoreGPRS() and getLeaderBoardGPRS() in onPostExecute method, but the leaderboard dialog is never opened...
Here is the relevant source code:
#Override
public void loginGPGS() {
try {
MyAsyncTask asyncTask_a = new MyAsyncTask();
asyncTask_a.execute();
} catch (final Exception ex) {
}
}
class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {
String errorMsg;
#Override
protected void onPreExecute() {
startLoginGPGS();
super.onPreExecute();
}
#Override
protected Boolean doInBackground(Void... v) {
return true;
}
#Override
protected void onPostExecute(Boolean success) {
if(success){
submitScoreGPGS(bestScore);
getLeaderboardGPGS();
}
}
}
public void startLoginGPGS() {
try {
// runOnUiThread(new Runnable() {
// public void run() {
gameHelper.beginUserInitiatedSignIn();
// }
// });
} catch (final Exception ex) {
}
}
#Override
public void submitScoreGPGS(int score) {
if(getSignedInGPGS()){
Games.Leaderboards.submitScore(gameHelper.getApiClient(),
getString(R.string.leaderboard1_id), score);
}
}

Have you trace your code??
Write something like...
Log.d("Trace","Point X"):
In the doInBackground method just before the return true, another one in the onPostExecute method just before the if and inside the if.
Take a look at your Logcat and come back...
Hope it helps.

You're executing your method on the UI thread, because onPostExecute() runs on the UI thread and your method has network execution..
You should move your method to the doInBackground() method

Related

AsyncTask with Glide for clearing Cache

It is throwing an error:
Caused by: java.lang.IllegalArgumentException: You must call this method on the main thread
Code:
Class CacheClearAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
Glide.get(getActivity()).clearDiskCache();
Glide.get(getActivity()).clearMemory();
return null;
}
#Override
protected void onPostExecute (Void result)
{
//Toast.makeText(getActivity(), "Cache cleared", Toast.LENGTH_LONG).show();
}
}
Setting preference on click event:
clearCacheBtnPref=findPreference(getResources().getString(R.string.pref_btn_clear_cache_key));
clearCacheBtnPref.setOnPreferenceClickListener(new
Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
new CacheClearAsyncTask().execute();
return true;
}
});
This can not be called in main thread as it is also throws errors and also it does not let me use asynctask.
Glide.get(getActivity()).clearDiskCache();
Glide.get(getActivity()).clearMemory();
clearDiskCache() must be called from background thread while clearMemory() from main thread so:
class CacheClearAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
Glide.get(getActivity()).clearDiskCache();
return null;
}
#Override
protected void onPostExecute (Void result) {
Glide.get(getActivity()).clearMemory();
}
}
I don't know your use case or app flow. But doInBackground is specifically used to do operations in background thread than Main UI thread.
Now if you need to do changes corresponding to Main UI thread in doInBackground , then do as following
#Override
protected Void doInBackground(Void... params) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Glide.get(getActivity()).clearDiskCache();
Glide.get(getActivity()).clearMemory();
}
});
return null;
}
For more examples on runOnUiThread refer this
Try this
Both method works in different thread.
clearDiskCache() must be called on a background thread.
clearMemory() must be called on the main thread.
You can't call both at once on the same thread.
void clearGlideCache()
{
new Thread()
{
#Override
public void run()
{
Glide.get(DemoActivity.this).clearDiskCache();
}
}.start();
Glide.get(DemoActivity.this).clearMemory();
}

AsycTask thread inside doInBackground runs after PostExecution has started

I am using AsyncTask and there are threads running inside the doInBackground method, isn't the purpose of AsyncTask is to let all the code finish executing inside the doInBackground and THEN go to PostExecute? Then why is it that some of my threads are running after the code block in PostExecution has started?
What should I do to solve this problem?
public class myActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
...
}
#Override
public void onClick(View view) {
new myTask().execute();
}
class myTask extends AsyncTask<Void, Void, Void> {
Boolean success;
#Override
protected void onPreExecute() {
success = true
}
#Override
protected Void doInBackground(Void... params) {
try {
Callback callback = new Callback() {
public void successCallback(String name, Object response) {
}
public void errorCallback(String name, error) {
success = false;}
};
} catch (Exception e) {
success = false;
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
if (success == true){
// do something
}
}
}
}
It is inside the error callback, that I want the success field to change to false. But the error callback runs after the postExecute method.
I think that you misunderstand the threading model.
AsyncTask does indeed execute doInBackground first, on a background thread, and then executes onPostExecute on the foreground thread, passing it the result from doInBackground.
However, from the wording of your question, it sounds like you are starting new threads from doInBackground. I'm sure that doInBackground does indeed complete before onPostExecute starts, but there is nothing that would cause the AsyncTask to wait for your additional threads to complete as well.
Edit:
It looks like you could skip the AayncTask altogether. The reason that you have callbacks is probably that method is already asynchronous
But note that you are only creating the callback, never using it. Perhaps you just left that part out?

Async error "Current thread must have a looper" when clicking retry button

I have an app that reads some data from a website and then creates TextViews for what is retrieved from the website. I have the process working through an AsyncTask. I've got it set up so that if there is a network error while trying to read from the website, a Retry button is shown. My code works perfect when it runs through the first time, but when I try to run the code from the onClick of the button, I get the following error:
java.lang.RuntimeException: An error occured while executing doInBackground()
(a few lines of error code)
Caused by: java.lang.IllegalStateException: The current thread must have a looper!
I even tried to have the onClick call an outside method as I saw someone recommend, but that didn't help. Here is some of the relevant code:
Async Task
private class DownloadListingTask extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... urls){
showLoadingPage();
try{
return getList(urls[0]);
}
catch (IOException e){
return sharedPreferences.getString("list_cache", "");
}
}
#Override
protected void onPostExecute(String result){
formatList(result);
}
}
Calling method
private void tryDownload(){
DownloadListingTask downloadListingTask = new DownloadListingTask();
downloadListingTask.execute(url);
}
onClick event
retryButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tryDownload();
}
});
So when the tryDownload() method is called from onCreateView it works fine, but when I try it from the onClick is when I get that error.
This code worked for me:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
primaryProgressBar.setVisibility(View.GONE);
}
});
For those who are still looking for answers and are using RxJava for async operations, this might be helpful.
When using Rxjava if you don't specify the observing thread then this error will come.
Caused by: java.lang.IllegalStateException: The current thread must have a looper!
so don't forget to add
subscribeOn(Schedulers.io())
observeOn(AndroidSchedulers.mainThread()) //required
disposableObserver = Observable.timer(2000, TimeUnit.MICROSECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Long>() {
#Override
public void accept(Long aLong) throws Exception {
//some code
}
});
Try to call showLoadingPage in onPreExecute method:
private class DownloadListingTask extends AsyncTask<String, Void, String>{
#Override
protected void onPreExecute(){
showLoadingPage();
}
#Override
protected String doInBackground(String... urls){
try{
return getList(urls[0]);
}
catch (IOException e){
return sharedPreferences.getString("list_cache", "");
}
}
#Override
protected void onPostExecute(String result){
formatList(result);
}
}

Android can't create handler inside that has not called Looper.loop

i am getting friends list from facebook and populating in list view it works fine but now i am trying to add Progress bar till the list view populates but getting exception i have tried searching but not found solution for my issue, here is my code:
public class FriendsProgress extends AsyncTask<Object, Void, Boolean>
{
#Override
protected Boolean doInBackground(Object... Params)
{
try
{
getFriendList();
friendAdapter = new FriendAdapter(Friends.this, R.layout.activity_friends, friendsList);
Friends.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
list.setAdapter(friendAdapter);
//list.setOnItemClickListener(EditStaff.this);
}
});
}
catch (Exception e)
{
System.out.println("StaffProgess Exception Caught:"+e.getMessage());
}
return Boolean.TRUE;
}
#Override
protected void onPreExecute()
{
friendsProgress=new ProgressDialog(Friends.this);
friendsProgress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
friendsProgress.setIndeterminate(true);
friendsProgress.setMessage("Loading...");
friendsProgress.setOwnerActivity(Friends.this);
friendsProgress.show();
}
#Override
protected void onPostExecute(Boolean Result)
{
friendsProgress.dismiss();
friendAdapter.notifyDataSetChanged();
}
}
here is getFriendsList function implementation:
public void getFriendList(){
Request request = Request.newMyFriendsRequest(Session.getActiveSession(), new Request.GraphUserListCallback() {
#Override
public void onCompleted(List<GraphUser> users, Response response) {
// TODO Auto-generated method stub
for(int i=0; i<users.size();i++)
{
GraphUser user = users.get(i);
Friend objFriend = new Friend();
objFriend.setFriendID(user.getId());
objFriend.setFriendName(user.getName());
Drawable dd =Friends.LoadImageFromWebOperations("http://graph.facebook.com/" + objFriend.getFriendID() + "/picture");
objFriend.setFriendPic(dd);
//objFriend.setFriendPic("http://graph.facebook.com/" + objFriend.getFriendID() + "/picture");
friendsList.add(objFriend);
//friendAdapter.notifyDataSetChanged();
Log.d("Friend's Id", objFriend.getFriendID());
Log.d("Friend's Name", objFriend.getFriendName());
//Log.d("Friend's Pic", objFriend.getFriendPic());
Log.d("Friend's List Count", Integer.toString(friendsList.size()));
}
}
});
Request.executeBatchAsync(request);
You shouldn't instantiate an Adapter and link it to a ListView inside the doInBackground() method, because it's running on a worker thread, and no operations connected to Android Views are permitted to be executed on a worker thread. Instead you might want to move this code
friendAdapter = new FriendAdapter(Friends.this, R.layout.activity_friends, friendsList);
Friends.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
list.setAdapter(friendAdapter);
//list.setOnItemClickListener(EditStaff.this);
}
});
to the onPostExecute() method. This is surely a better designed solution. Hope this helps.
Try this,
ProgressDialog dialog;
protected void onPreExecute()
{
dialog = new ProgressDialog(Friends.this);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMax(100);
dialog.show();
}
Run Ui Thread inside onPostExecute() method as follows :
runOnUiThread(new Runnable() {
#Override
public void run() {
friendAdapter = new FriendAdapter(Friends.this, R.layout.activity_friends, friendsList);
list.setAdapter(friendAdapter);
friendsProgress.dismiss();
friendAdapter.notifyDataSetChanged();
}
});

ProgressBar display with some delay in on click of option menu

I am facing the issue with displaying progressbar onItem selected in option menu.
My code is here:
case R.id.mnuLogout:
showDialog(Constants.PROGRESS_DIALOG);
closeOptionsMenu();
if(MyApp.IsLoggedOut())
handler.sendEmptyMessage(Constants.LOGOUT);
else
handler.sendEmptyMessage(Constants.ERROR_MSG);
Progressbar is displayed after completion of IsLogged method.
You're calling get() right after the AsyncTask as executed and lose asynchronous behavior because this method waits until task is finished. You should add all the code in try/catch block to AsyncTask.onPostExecute() method and also dismiss the dialog from this method.
void doLogout() {
new LogoutTask().execute();
}
void dispatchLogoutFinished() {
dismissDialog(Constants.PROGRESS_DIALOG);
if (MyApp.IsLoggedOut()) {
// do something
} else {
// do something else
}
}
private class LogoutTask extends AsyncTask<Void, Void, Void> {
protected void onPreExecute() {
TheActivity.this.showDialog(Constants.PROGRESS_DIALOG);
}
protected Void doInBackground(Void... params) {
return null;
}
protected void onPostExecute(Long result) {
TheActivity.this.dispatchLogoutFinished();
}
}
And I don't think you need to send messages to the handler. The dispatchLogoutFinished() is executed on the UI thread, so there's no need for synchronization.

Categories

Resources