onPostExecute is getting executed before doInBackground - android-asynctask

I am stuck with the following issue. I tried searching for answers but none of the responses could help me so i am asking this question here. Any response will be greatly appreciated!
I am using this below AsyncTask to use the login methods exposed by the Firebase API. However when i invoke new LoginOperation().execute() at the click of login button, i am not seeing the expected results. I am pasting the code below and the Logcat output.
I would like to know why onPostExecute is getting executed before doInBackground? Please note i am using a valid email id & password, so i should have been able to login properly.
Code:
private class LoginOperation extends AsyncTask<Void, Void, Boolean> {
protected Boolean doInBackground(Void... params) {
try{
authClient.loginWithEmail(emailid.getText().toString(),password.getText().toString(), new SimpleLoginAuthenticatedHandler() {
public void authenticated(
com.firebase.simplelogin.enums.Error error, User user) {
if(error != null) {
// There was an error logging into this account
loginStatus=false;
errorMsg=error.name();
Log.d(appName, "Inside if block in doInBackground of LoginOperation");
}
else {
// We are now logged in
loginStatus=true;
Log.d(appName, "Inside else block in doInBackground of LoginOperation");
}
}
});
}
catch (Exception e)
{
e.printStackTrace();
}
return Boolean.valueOf(loginStatus);
}
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (result.booleanValue()) {
toastMsg="User logged in successfully";
Log.d(appName, "Inside onPostExecute success of LoginOperation");
}
else
{
toastMsg="Error in login";
Log.d(appName, "Inside onPostExecute failure of LoginOperation");
}
TextView displayStatus = (TextView) findViewById(R.id.displayStatus);
displayStatus.setText(toastMsg);
}
protected void onPreExecute() {
super.onPreExecute();
}
protected void onProgressUpdate(Void... values) {}
}
Code invoked on Login click:
public void onLogin(View arg0)
{
Log.d(appName, " email id is " + emailid.getText().toString());
Log.d(appName, " password is " + password.getText().toString());
try {
Boolean finalStatus= new LoginOperation().execute().get(5000, TimeUnit.MILLISECONDS);
Log.d(appName, " final Status is: " + finalStatus.booleanValue());
}
LogCat:
01-27 17:50:02.054: D/LOGIN(984): email id is abc#gmail.com
01-27 17:50:02.054: D/LOGIN(984): password is abc123
01-27 17:50:02.082: D/LOGIN(984): final Status is: false
01-27 17:50:02.082: D/LOGIN(984): Inside onPostExecute failure of LoginOperation
01-27 17:50:05.502: D/LOGIN(984): Inside else block in doInBackground of LoginOperation
Expected result:
Inside else block in doInBackground of LoginOperation
Inside onPostExecute success of LoginOperation

You don't need your AsyncTask because the class you are using in doInBackground seems to already perform its task in a background thread. Move the code in doInBackground somewhere to the UI thread and move your code from onPostExecute into the SimpleLoginAuthenticationHandler.
Currently, onPostExecuted is called immediately, because it just starts a new background thread and comes back immediately.

Most likely this is because SimpleLoginAuthenticatedHandler.authenticated() is executed asynchronously. It looks you don't need AsyncTask at all.

My guess is that loginWithEmail() runs within a Thread. That means that when you call this method, the thread is indeed run but that doesn't mean it has ended its execution, so maybe it's running paralelly, you get back, finish the doInBackground() method and it joins the onPostExecute() method.
I would remove the AsyncTask if it's that way, it's not necessary.

Related

Response to someone which send his first DM to you in JDA

Could I response to someone who send his first DM to me in JDA?
This question will depend on what you need, you can use the
public void onPrivateMessageReceived(#Nonnull PrivateMessageReceivedEvent event) {
//code
}
method to get the private channel for DM's.
After that, you could check the history with the user. This would be example code, so you need to edit it to your needs:
#Override
public void onPrivateMessageReceived(#Nonnull PrivateMessageReceivedEvent event) {
if (event.getUser().isBot()) return; // Don't do anything if the user is bot (aka, self)
if (event.getChannel().getHistory().size() < 2) { //Made it <2 in case array starts with 0
event.getChannel().sendMessage("HI THIS IS THE MESSAGE I WANT TO SEND").queue();
}
}

How do i exit from a method and run another when a condition is triggered, JDA discord wrappper

public void onMessageReceived(MessageReceivedEvent event) {
String[] messagelements = event.getMessage().getContentRaw().split("\\s+");
if (event.getMessage().getContentRaw().equalsIgnoreCase("what is the number beside " + wordanswer) && event.getAuthor().isBot()){
time = System.currentTimeMillis();
while (System.currentTimeMillis() - time <= 8000){
if (answered.equalsIgnoreCase("answered")) {
return;
}else {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}
if (answered.equalsIgnoreCase("notanswered")){
event.getChannel().sendMessage("times up").queue();
}
}
}
public void onMessageReactionAdd (MessageReactionAddEvent event) {
Thread.currentThread().setPriority(10);
if (event.getUser().equals(worker)) {
if (answered.equalsIgnoreCase("notanswered")){
if (event.getReactionEmote().getName().equalsIgnoreCase(emoteanswer)){
event.getChannel().sendMessage("Correct!").queue();
}
else{
event.getChannel().sendMessage("Wrong").queue();
}
answered = "answered";
}
}
}
the variable answered is to check if the user has already answered the question. However, when my timer starts, it does not detect any activity from the the onMessageReactionAdd and only reacts to it after the timer ends in which "times up" will always be sent then the Wrong/Correct option will then be sent. How do i run both methods simultanously or stop a method and run another when a condition happens. (note that the reaction is the user answer). The timer gives a time limit on the answering the qn and the player will be wrong if they fail to answer within the time limit. Some people suggested using a new thread but i haven’t mastered java and need some help doing that
You could use either an eventwaiter, or create a response based on a state-machine (Credits to Minn for posthing this)
Depending on your use case, this will differ on how you're going to use it.

Xamarin "Sorry, this video cannot be played"

How can i handle this error?
please help me out of this situation.
private void previewVideo(){
try{
var path = Android.Net.Uri.Parse(App._file.AbsolutePath);
preview.SetVideoURI (path);
preview.Start ();
}
catch(Exception e){
e.GetBaseException ();
}
}
Your'e lucky that I was following your previous question. Please try to have your questions as detailed as possible so it's easier for us to analyze and possible replicate the error.
To be able to set an error listener on the VideoView, the VideoView needs an object that implements the Android.Media.MediaPlayer.IOnErrorListener interface.
You can accomblish that by letting your Activity implement the previous mentioned interface, and setting the Activity as the ErrorListener for the VideoView
public class MainActivity : Activity, Android.Media.MediaPlayer.IOnErrorListener
{
...
protected override void OnCreate(Bundle bundle)
{
...
preview = FindViewById<VideoView> (Resource.Id.SampleVideoView);
preview.SetOnErrorListener(this); // <- Set the error listener
...
}
...
//The implementation of MediaPlayer.IOnErrorListener
public bool OnError(MediaPlayer player, MediaError error, int extra)
{
// Do Something here because error happened
}
...
}
By doing this, when error occurs in the VideoView the VideoView will call the public OnError method.
From the Android Docs of OnErrorListener you can see what the OnError method should return.
Returns:
True if the method handled the error, false if it didn't. Returning false, or not having an OnErrorListener at all, will cause the OnCompletionListener to be called.

Chromecast receiver using sendLoadComplete() doesn't update status

I'm writing a Chromecast receiver to play different kind of contents (including embedded flash videos). I'd like to use my own JS library to create the player canvas, not to rely on the html video element.
I'm currently blocked because I can't get a media to be loaded using a custom behaviour :
Receiver :
Nothing fancy in the HTML, I just load my library in the #mediaWrapper div. Then I create a MediaManager from it.
var node = $( "#mediaWrapper" )[0];
var phiEngine = new phi.media.Player( node );
window.mediaManager = new cast.receiver.MediaManager( phiEngine );
window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
/* Override Load method */
window.mediaManager['origOnLoad'] = window.mediaManager.onLoad;
window.mediaManager.onLoad = function (event) {
console.log('### Application Load ', event);
/* Custom code (load lib, set metadata, create canvas ...) */
window.mediaManager.sendLoadComplete(); // Doesn't seem to do anything
// window.mediaManager['origOnLoad'](event);
// -> Fails 'Load metadata error' since url is not a video stream
// -> ex: youtube url
}
/* Will never be called */
window.mediaManager['origOnMetadataLoaded'] = window.mediaManager.onMetadataLoaded;
window.mediaManager.onMetadataLoaded = function (event) {
...
}
Sender :
I use my own android application to cast to the device. I can't use the Companion library because it will be a Titanium module.
private void createMediaPlayer() {
// Create a Remote Media Player
mRemoteMediaPlayer = new RemoteMediaPlayer();
mRemoteMediaPlayer.setOnStatusUpdatedListener(
new RemoteMediaPlayer.OnStatusUpdatedListener() {
#Override
public void onStatusUpdated() {
Log.e(TAG, "onStatusUpdated");
}
}
});
mRemoteMediaPlayer.setOnMetadataUpdatedListener(
new RemoteMediaPlayer.OnMetadataUpdatedListener() {
#Override
public void onMetadataUpdated() {
Log.e(TAG, "onMetadataUpdated");
}
});
try {
Cast.CastApi.setMessageReceivedCallbacks(mApiClient,
mRemoteMediaPlayer.getNamespace(), mRemoteMediaPlayer);
} catch (IOException e) {
Log.e(TAG, "Exception while creating media channel", e);
}
mRemoteMediaPlayer
.requestStatus(mApiClient)
.setResultCallback(
new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
#Override
public void onResult(MediaChannelResult result) {
Log.e(TAG, "Request status : ", result.toString());
if (!result.getStatus().isSuccess()) {
Log.e(TAG, "Failed to request status.");
}
}
});
}
private void loadMedia( MediaInfo mediaInfo, Boolean autoplay ) {
try {
mRemoteMediaPlayer.load(mApiClient, mediaInfo, autoplay)
.setResultCallback(new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
#Override
public void onResult(MediaChannelResult result) {
Log.e(TAG, "loadMedia ResultCallback reached");
if (result.getStatus().isSuccess()) {
Log.e(TAG, "Media loaded successfully");
} else {
Log.e(TAG, "Error loading Media : " + result.getStatus().getStatusCode() );
}
}
});
} catch (Exception e) {
Log.e(TAG, "Problem opening media during loading", e);
}
}
Expected behaviour :
I basically first call createMediaPlayer() once, then call loadMedia(...). The first call to loadMedia will show nothing in the log : nor success or fail. Next calls issue with errorCode 4.
I get the load event on the receiver side. But, back to the sender side, I can't manage to end the load phase and get a media session to be created.
I was expecting sendLoadComplete() to do so but I might be wrong. How can I have the media status to update and the loadMedia ResultCallback to be reached ?
My goal is to use RemoteMediaPlayer.play(), pause(), ... but for now I get stuck with 'No current media session' because the media isn't loaded yet.
Also, I'd really enjoy to be able to log any message the Sender receives, before being processed. Is it possible ?
Hope I did not forget any information,
Thanks for your help !
edit: I solved this by using a custom message channel since it seems that I can't use RemoteMediaPlayer the way I want to.
I believe the error code 4 you are receiving is bogus; see https://plus.google.com/u/0/+JimRenkel2014/posts/aY5RP7X3QhA . As noted there, I created a Chromecast issue for this (https://code.google.com/p/google-cast-sdk/issues/detail?id=305&thanks=305&ts=1403833532). Additional support for this issue will help it get fixed faster! :-)
.sendLoadComplete(true)
The boolean value helped me to receive the loaded event on sender. Might help you as well.

StackOverFlow Exception, alternatives for my function?

I've created a program that at some point has to log in to some website. If something goes wrong, I want it to wait for some time, say 2 seconds, and then try again. so the function looks something like this:
public void log_in ()
{
try
{
//login code
}
catch
{
Thread.Sleep(2000);
log_in();
}
}
But this code started to give me StackOverFlowExeptions every now and then. Does anyone know how to solve that?
You're getting a stack overflow exception because every time you call log_in() you're adding the function to the stack. This this:
public void log_in ()
{
while (true) {
try
{
//login code
return;
}
catch
{
}
}
}
what's because if code can't login at all it keeps creating new function call each time on the stack. Next code would work:
public void log_in ()
{
while(true) {
try {
//login code
return;
}
catch {
Thread.Sleep(2000);
}
}
}
But overall you shouldn't try to login endlessly, after several time report error to user/admin.

Resources