Does Retrofit Make Network Calls on Main Thread

Does Retrofit make network calls on main thread?

Retrofit methods can be declared for either synchronous or asynchronous execution.

A method with a return type will be executed synchronously.

@GET("/user/{id}/photo")
Photo getUserPhoto(@Path("id") int id);

Asynchronous execution requires the last parameter of the method be a Callback.

@GET("/user/{id}/photo")
void getUserPhoto(@Path("id") int id, Callback<Photo> cb);

On Android, callbacks will be executed on the main thread. For desktop applications callbacks will happen on the same thread that executed the HTTP request.

Retrofit also integrates RxJava to support methods with a return type of rx.Observable

@GET("/user/{id}/photo")
Observable<Photo> getUserPhoto(@Path("id") int id);

Observable requests are subscribed asynchronously and observed on the same thread that executed the HTTP request. To observe on a different thread (e.g. Android's main thread) call observeOn(Scheduler) on the returned Observable.

Note: The RxJava integration is experimental.

Is retrofit post data to api in background thread automatically

Retrofit by default doesn't run network requests on main thread (if thats what you need to know), so you don't really need to do anything in that regard.

but if you are using Kotlin, i would highly suggest you to use Retrofit with Coroutines, which is not mandatory for kotlin applications but it is more efficient and is built in kotlin itself so you don't need to install any third party lib.

here is a useful guide on how to use Retrofit with Coroutines:
link

Call retrofit inside other mathod and return result to main thread

Update your api call method:

fun getStoreTitles(callback : Callback<List<sample>>) {
var responseResult:List<sample>
responseResult= listOf(sample("","",""))
val service = getRetrofitInstance()!!.create(GetDataService::class.java)
val call = service.getAllPhotos()
call.enqueue(callback);

}

you have to call like this :

val FrameWork=StoreTitle()
FrameWork.getStoreTitles(object : Callback<List<sample>> {
override fun onResponse(call: Call<List<sample>>, response: Response<List<sample>>) {
val responseResult : List<sample>? =response.body()
//handle your success
}
override fun onFailure(call: Call<List<sample>>, t: Throwable) {
//handle your failure
}
})

Retrofit Execute Method Network Error on Main Thread

One option would be to use RXJava + Retrofit to chain your API calls.

Although the most straightforward solution would just be to execute all of your code on another thread. There are numerous ways to achieve this, using Kotlin Coroutines is an option in Android.

If you're executing the code in a fragment, activity etc:

viewLifecycleOwner.lifecycleScope.launch {

searchResponse = searchCall.execute()

...

}

Single causes either Network on Main Thread or View Root from Wrong Thread exceptions

There was an RxJava gradle dependency that was conflicting with the RxKotlin dependency, I think. Removing it fixed the problem. I also took some of the work from onSuccess and added an operator, which is probably better practice anyway:

fun loadStaffCalendar() {
var calendarParser = CalendarParser()
calendarParser.getSingleBearCal()
.subscribeOn(Schedulers.io())
.map { calendarParser.parseStringIntoSchedule(it.string()) }
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy(
onError = {error(it.localizedMessage.toString())},
onSuccess = {view.loadToAdapter(it)})
}

Gradle looks like:

implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxkotlin:2.4.0'

Retrofit callback on main thread

Where does the parsing happen (let's assume I am using an XML converter for process response). Is this main thread, or a different one ? Does it depend on converter implementation ?

Always a background thread no matter the converter you use.

If I have to include some (heavy) validation rule/business rules, do I need to spawn a new thread inside callable ? Or is it fine to have it done in the Callback methods ?

This is fairly subjective and there's a lot of ways to tackle it. The Callback will be executed on the main thread by default.

You can change the thread on which callbacks will be invoked by supplying a custom Executor to the RestAdapter.Builder. This will affect all services constructed by that RestAdapter, however, which may not be what you want.

There's nothing wrong with spawning another thread (or enqueueing on an executor) from the Callback if the work you want to be done can be done in parallel with updating the UI (for example, light-weight caching).

If the expensive work must be done before notifying the UI then you are better off switching the method to be synchronous (no callback) and doing the threading yourself. This way you can do expensive operations before and after the HTTP call (file i/o, caching, transforming, validating, etc.).

We currently use RxJava (of which Retrofit has experimental support) for what you are asking:

interface Foo {
@GET("/")
Observable<Foo> getFoo(String bar);
}

foo.getFoo()
.mapMany(new ExpensiveOperationFunction())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<TransformedFoo>() { .. });

Alert Mainthread from retrofit when data is ready

Try this..
First Create an interface ..Let's call it OKCallback.

public interface OKCallback {
void onSuccess(String result);

void onFailure(String result);

}

Then in your method that launches the retrofit request, pass final OKCallback okCallback like this..

 public void NetworkCall(final OKCallback okCallback){

...........
call.enqueue(new Callback<Dashboard>() {
@Override
public void onResponse(Call<Dashboard> call, Response<Dashboard> response) {

realm.beginTransaction();
dashboard = realm.copyToRealmOrUpdate(response.body());
realm.commitTransaction();

// heavy work : insert in data in multiple text views
okCallback.onSuccess(parcel);

}

Finally simply (ActivityX implements OKCallback) in any class or activity and you should be able to do your heavy work there..You can also wrap your data in the onSuccess methods with a Handler as shown.

 @Override
public void onSuccess(String result) {
Handler handler = new Handler(ActivityX.this.getMainLooper());

//process result and
handler.post(new Runnable() {
@Override
public void run() {

//heavy work done here will run on UI thread
}
});
}


Related Topics



Leave a reply



Submit