How cancel network request in retrofit and rxjava - retrofit

I have a multiple buttons; When I press new button, previous(with another button) running request should be interrupted and new runs. How to realize it?
for (button : Buttons) {
button.setOnClickListener(b -> networkApi.getLongContentFromUrl(url)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<JsonElement>() {
#Override
public void onCompleted() {}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(JsonElement jsonElement) {
//do with result
}
}));
}

You can have a common SerialSubscription and assign your subscriber to it on button click. It will unsubscribe and thus cancel your previous stream:
SerialSubscription serial = new SerialSubscription();
for (Button btn : buttons) {
btn.setOnClickListener(e -> {
Subscriber<JsonElement> s = new Subscriber<JsonElement>() {
#Override
public void onCompleted() {}
#Override
public void onError(Throwable e) {}
#Override
public void onNext(JsonElement jsonElement) {
//do with result
}
};
serial.set(s);
networkApi.getLongContentFromUrl(url)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(s);
});
}

Related

Xamarin.Forms : Need to go back to previous page on back button press even if entry has focus

If my entry field has focus and i click on hardware back button, the entry field looses focus but i am not able to navigate to previous page. I have to hit the back button again. I know this is the expected behaviour, but i need to navigate to the previous page on the first back button press itself. Need some help regarding this.
This behavior is by design.But you could use custom renderer and custom a EditText to achieve the effect.
1.create a CustomEntry :
public partial class CustomEntry:Entry
{
public static readonly BindableProperty BackPressProperty=BindableProperty.Create("BackPress", typeof(EventHandler), typeof(CustomEntry), null);
public event EventHandler BackPress;
public void OnBack()
{
EventHandler eventHandler = this.BackPress;
eventHandler?.Invoke((object)this, EventArgs.Empty);
}
}
2.create a custom EditText MyEditText in your Android project:
class MyEditText: FormsEditText
{
public MyEditText(Context context) : base(context)
{
}
public override bool OnKeyPreIme([GeneratedEnum] Keycode keyCode, KeyEvent e)
{
if (keyCode == Keycode.Back)
{
if (listener != null)
{
listener.onKeyBack();
return true;
}
}
return base.OnKeyPreIme(keyCode, e);
}
private OnEditTextKeyBackListener listener;
public void setOnEditTextKeyBackListener(OnEditTextKeyBackListener listener)
{
this.listener = listener;
}
public interface OnEditTextKeyBackListener
{
void onKeyBack();
}
}
3.custom EntryRenderer MyEntryRenderer:
[assembly: ExportRenderer(typeof(CustomEntry), typeof(MyEntryRenderer))]
namespace EntryCa.Droid
{
class MyEntryRenderer:EntryRenderer,OnEditTextKeyBackListener
{
private Context context;
private EditText editText;
public MyEntryRenderer(Context context) : base(context)
{
this.context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
MyEditText editText = new MyEditText(context);
editText.setOnEditTextKeyBackListener(this);
editText.SetSingleLine(true); //this and below line to set done key
editText.ImeOptions = ImeAction.Done;
SetNativeControl(editText);
}
public void onKeyBack()
{
hideSoftInput();
((CustomEntry)Element).OnBack();
}
InputMethodManager mInputMethodManager = (InputMethodManager)Android.App.Application.Context.GetSystemService(Context.InputMethodService);
public void hideSoftInput()
{
if (mInputMethodManager != null)
{
mInputMethodManager.HideSoftInputFromWindow(WindowToken, HideSoftInputFlags.NotAlways);
}
}
}
}
4.use in your page.xaml:
<local:CustomEntry HorizontalOptions="StartAndExpand" WidthRequest="200" BackPress="CustomEntry_BackPress"></local:CustomEntry>
in your page.xaml.cs:
private void CustomEntry_BackPress(object sender, EventArgs e)
{
Navigation.PopAsync();
}

javafx: Progress bar to show the progress of the process?

I want to show progress bar while a functionality is running. What is the best way to show it? Basically I am building a program to send multiple mails on a single click. While sending the mail I want to show progress bar while sending the mails.
The best solution in this case is using a Task.
Example:
Task<Parent> yourTaskName = new Task<Parent>() {
#Override
public Parent call() {
// DO YOUR WORK
//method to set progress
updateProgress(workDone, max);
//method to set labeltext
updateMessage(message);
}
};
//ProgressBar
ProgressBar pBar = new ProgressBar();
//Load Value from Task
pBar.progressProperty().bind(yourTaskName.progressProperty());
//New Loading Label
Label statusLabel = new Label();
//Get Text
statusLabel.setText("Loading...");
//Layout
VBox root = new VBox(statusLabel, pBar);
//SetFill Width TRUE
root.setFillWidth(true);
//Center Items
root.setAlignment(Pos.CENTER);
//SetOnSucceeded methode
yourTaskName.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent event) {
System.out.println("Finish");
}
});
//Start Thread
Thread loadingThread = new Thread(yourTaskName);
loadingThread.start();
Hope this helps you.
P.S.: The code in the task run as a Thread...
I implemented what you want last time ,If you want to show progressIndicator or progressBar when sending is running ,try this part of code
senderThreadlive = new Thread(new Runnable() {
#Override
public void run() {
try {
Platform.runLater(new Runnable() {
#Override
public void run() {
ProgressIndicator WaitingSend=new ProgressIndicator();
WaitingSend.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
WaitingBox.getChildren().add(WaitingSend);//this is an HBOX
SendMailButton.setDisable(true);
SendMailButton.setText("sending in progress");
}
});
//call Your method of sending
SimpleMail.EmailSender.sendEmail(MailSenderTxt.getText(), MotMailTxt.getText(), DestMailTxt.getText(), ObjetMailTxt.getText(), org.jsoup.Jsoup.parse(ContentMail.getHtmlText()).text());
Platform.runLater(new Runnable() {
#Override
public void run() {
WaitingSend.setProgress(0);
WaitingSend.setVisible(false);
SendMailButton.setDisable(false);
SendMailButton.setText("Send");
}
});
} catch (AuthenticationFailedException e) {
Platform.runLater(new Runnable() {
#Override
public void run() {
//Your popUp here
}
});
} catch (SendFailedException e) {
Platform.runLater(new Runnable() {
#Override
public void run() {
//Your popUp here
}
});
} catch (MessagingException e) {
Platform.runLater(new Runnable() {
#Override
public void run() {
//Your popUp here
}
});
} catch (Exception ex) {
Platform.runLater(new Runnable() {
#Override
public void run() {
//Your popUp here
}
});
}
}
});
senderThreadlive.start();
Just use javafx.scene.control.ProgressBar
Documentation:
http://docs.oracle.com/javafx/2/ui_controls/progress.htm

How can I extend a Retrofit 2.0 Call?

I want to achieve something like this:
MyCall<MyResponse> call = service.login(loginRequest);
call.enqueue(
new Runnable() {
#Override
public void run() {
// onResponse
}
}, new Runnable() {
#Override
public void run() {
// onFailure
}
});
so that when I have to make a call I don't need to parse the response in each callback and the code is a little lighter and reusable.
I tried the code from this snippet but I get the error:
Unable to create call adapter for XXXX.
What am I missing?
I did not extend Call but I extend Callback, it's also help to make the code is a little lighter and reusable.
public abstract class CustomCallback<T> implements Callback<T> {
#Override
public void onResponse(final Response<T> response, Retrofit retrofit) {
Runnable runnable = new Runnable() {
#Override
public void run() {
onRequestSuccess(response);
}
};
runnable.run();
}
#Override
public void onFailure(final Throwable t) {
Runnable runnable = new Runnable() {
#Override
public void run() {
onRequestFail(t);
}
};
runnable.run();
}
public abstract void onRequestSuccess(Response<T> response);
public abstract void onRequestFail(Throwable t);
}
Then when you call enqueue():
call.enqueue(new CustomCallback<YourObject>() {
#Override
public void onRequestSuccess(final Response<YourObject> response)
{
}
#Override
public void onRequestFail(final Throwable t) {
}
});
Hope it helps
If you're referring to the snippet below Jake Wharton's post then the issue should be that you're including a call to RxJavaCallAdapterFactory.create() & your call interface is not an observable. So remove that line.

Dispose JavaFX Tasks

I have a static BorderPane with ContextMenu insight Task
Task task = new Task()
{
#Override
protected Void call() throws Exception
{
Platform.runLater(new Runnable()
{
#Override
public void run()
{
try
{
contextMenu = new ContextMenu();
MenuItem item1 = new MenuItem("About");
item1.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent e)
{
System.out.println("About");
}
});
MenuItem item2 = new MenuItem("Preferences");
item2.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent e)
{
System.out.println("Preferences");
}
});
MenuItem item3 = new MenuItem("Close");
item3.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent e)
{
}
});
contextMenu.getItems().addAll(item1, item2, item3);
bp.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>()
{
#Override
public void handle(ContextMenuEvent event)
{
contextMenu.show(bp, event.getScreenX(), event.getScreenY());
event.consume();
}
});
bp.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>()
{
#Override
public void handle(MouseEvent event)
{
contextMenu.hide();
}
});
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally
{
}
}
});
return null;
}
};
new Thread(task).start();
I noticed that when I close the component which holds the BorderPane the Java Threads are not disposed they are still initialized into the memory. I'm not sure is this caused by the static BorderPane. After the Task is completed the Java Thread should be disposed. Any idea why is this happening?
The problem is not a Task, but the anonymous classes in your Runnable.
In the next piece of code:
bp.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>()
{
#Override
public void handle(ContextMenuEvent event) {
//...
}
});
you introduce an anonymous class extending EventHandler which holds inner link to a Runnable. To solve that you can use nested static class instead.
P.S.: Unfortunately you can't make anonymous class static in Java, see Is it possible to make anonymous inner classes in Java static?

Progress bar with thread

Now a days it's my first step in android. I am simply trying to implement progress bar with with a "Download" Button. When i press download button progress bar keep on progressing but when the whole progress gets over i am not able to hide progress bar. Here is my code. please help me.
public class ProgressBarDemo extends Activity
{
ProgressBar pb;
Button bt;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.progressbar);
pb = (ProgressBar) findViewById(R.id.progressBar1);
bt = (Button) findViewById(R.id.button1);
pb.setVisibility(View.VISIBLE);
bt.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Thread timer = new Thread()
{
public void run()
{
try
{
for(int i=0; i<=50; i ++)
{
pb.incrementProgressBy(i);
sleep(1000);
}
pb.setVisibility(View.INVISIBLE);
Toast.makeText(ProgressBarDemo.this, "Thank you for downloading", Toast.LENGTH_SHORT).show();
}catch(Exception e){}
}
};
timer.start();
}
});
}
}
You should only modifiy ui elements from the mainThread (the UI Thread) try
pb.post(new Runnable() {
#Override
public void run() {
pb.setVisibility(View.INVISIBLE);
}
})
instead.
Maybe u have to use the same thing for incrementing your progressbar. Alternativley you could use the AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html class. onProgressUpdate and onPostExecute are called in the UIThread automatically.
you can also use AsynTask that is a better solution...
public class ProgressBarDemo extends Activity
{
ProgressBar pb;
Button bt;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pb = (ProgressBar) findViewById(R.id.progressBar1);
bt = (Button) findViewById(R.id.button1);
pb.setVisibility(View.VISIBLE);
bt.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
new AsynTasks().execute();
}
});
}
class AsynTasks extends AsyncTask<Void, Integer, Void>
{
#Override
protected Void doInBackground(Void... params) {
for(int i=1;i<=100;i++)
{
SystemClock.sleep(1000);
publishProgress(i);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
pb.setVisibility(View.INVISIBLE);
Toast.makeText(ProgressBarDemo .this, "Thank you for downloading", Toast.LENGTH_SHORT).show();
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
pb.setProgress(values[0]);
}
}
}
You should not do UI task from different thread.Use this...
public class ProgressBarDemo extends Activity
{
ProgressBar pb;
Button bt;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pb = (ProgressBar) findViewById(R.id.progressBar1);
bt = (Button) findViewById(R.id.button1);
pb.setVisibility(View.VISIBLE);
bt.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Thread timer = new Thread()
{
public void run()
{
try
{
for(int i=1; i<=100; i ++)
{
pb.setProgress(i);
sleep(100);
}
}catch(Exception e){}
finally{
runOnUiThread( new Runnable() {
public void run() {
pb.setVisibility(View.INVISIBLE);
Toast.makeText(ProgressBarDemo .this, "Thank you for downloading", Toast.LENGTH_SHORT).show();
}
});
}
}
};
timer.start();
}
});
}
}

Resources