Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Context: In a previous Android application I have developed, I used an event bus (otto by Square) to handle async task results (for example: the result of a server request is posted on the bus and somewhere in the application I intercept that response). Although it did the job, in some article I've read it was mentioned that using such a bus is rather a bad idea as it's considered an antipattern.
Why is that so? What are some alternatives to using an event bus when dealing with results of async operations? I know that, most of the time, there is no standard way to handle things, but is there "a more canonical" method?
Use RxJava and Retrofit for asynchronous network calls. RxJava provide out of the box support for Retrofit.
Return Observable from retrofit interface.
#GET("/posts/{id}")
public Observable<Post> getData(#Path("id") int postId);
Use it in your activity class -
retrofitBuilderClass.getApi()
.getData()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer < List < Data >> () {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(List < Data > data) {
// Display data
}
});
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I'm trying to update my Android views using some data that I've got on a Firebase Realtime DB. Since I'm using Kotlin, I've encountered some problems doing this simple thing. I'm not an expert on Realtime DB, I've just discovered that the calls to the DB are made asynchronously, and this means I've got to use the data inside the onDataChange function.
I also discovered that Kotlin doesn't let me change the value of a View that I passed as a parameter to some function (like the one I created to update that View using the data retrieved from the DB). So I'm counting on you for this.
What's the best way to retrieve data from Firebase and use that data to update my Views? I would like to have some clean code, like different functions that do the right thing, without having a pile of code in the onCreate method of my MainActivity.
Maybe something along these lines:
fun fetchFeed(): LiveData<List<Feed>> {
val result: MutableLiveData<List<Feed>> = MutableLiveData()
firestore.collection("feeds")
.addSnapshotListener { collectionSnapshot, exception ->
if (exception != null) {
//...handle error
return#addSnapshotListener
}
if (collectionSnapshot == null || collectionSnapshot.isEmpty) {
//...no data or no collection
return#addSnapshotListener
}
val value: MutableList<Feed> = arrayListOf()
collectionSnapshot.documents.map {
value.add(it.toObject(Feed::class.java))
}
data.postValue(value)
}
return result
}
class FeedFragmentViewModel: ViewModel() {
//ApiService is a singleton or an DAO eg... where your fetchFeed is declared or have access to it
val result: LiveData<List<Feed>> = ApiService.fetchFeed()
}
class FeedFragment: Fragment() {
override onActivityCreated() {
//initialize view model -> in docs
viewModel.result.observe(this, Observer {
myListAdapter.updateList(it)
})
}
}
It is not a complete solution but along these lines I think you should be able to incorporate realtimedb in it. Long story short you want to observe live data which represents the data from realtime db. When ever those c hange your callback in observer gets called where you can update the UI accordingly
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
My android app communicate with back end service through REST API . I want to mock out this API to quickly develop the front end. I am using android volley as client side networking library..
I would store mock data as json in my assets folder and create my data from these json files:
fun getJsonFromAssets(context: Context, jsonPath: String): String? {
return try {
context.assets.open(jsonPath).bufferedReader().use{
it.readText()
}
} catch (e: IOException) {
null
}
}
and then get the object like (here for example for a list):
val list = gson.fromJson<List<MyObject>>(jsonString, object : TypeToken<List<MyObject>>() {}.type)
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
This post was edited and submitted for review 8 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
Please explain a use cases and pros and cons of each approach.
Use of interface.
fun doSomethingWithCallback(callback: Callback) {
// Do something
callback.call()
}
Use of high-order function.
fun doSomethingWithCallback(callback: () -> Unit) {
// Do something
callback()
}
Option 1
With option 1 you're not able to call it passing a lambda. For example this does not compile:
doSomethingWithCallback1 { print("helloWorld") }
Interestingly if the same method were defined in Java:
void doSomethingWithJavaCallback(JavaCallback callback) {
// Do something
callback.call();
}
Then you can call it using a lambda from Kotlin. This is because Kotlin only does SAM-conversion for functions defined in Java.
Option 2
In contrast if you go with option 2 you do get to call it using a lambda. And it will work both when calling it from Kotlin and from Java.
Option 3
As mentioned in the comments a third option is using a type alias like this:
typealias Callback = () -> Unit
fun doSomethingWithCallback5(callback: Callback) {
// Do something
callback()
}
You get to keep the type in the function signature and use lambdas on the call site.
You can use with a lambda :
doSomethingWithCallback { // do whatever you want }
I usually use lambda function by this one:
var doSomething: ((Any) -> Unit)? = null
and invoke callback:
doSomething?.invoke(any)
finally as same as listener:
youClass.doSomething = { any ->
// this is callback
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
So I have a function that returns a value that is of future. When this function executes I want to extract the string from the future. How should I do this?
Future<String> coverImage(id, space) {
String link = 'https://cdn.contentful.com/spaces/$space/assets/$id?access_token=1d4932ce2b24458e85ded26532bb81184e0d79c1a16c5713ec3ad391c2e8f5b3';
return http.get(link).then((response) => decodeToImage(decodeJson(response.body)));
}
this function return Future<String>, i want to extract to string when i am using with image widget
Future someMethod() async {
String s = await someFuncThatReturnsFuture();
}
or
someMethod() {
someFuncTahtReturnsFuture().then((s) {
print(s);
});
}
There is no way to go from async (Future) to sync execution.
async/await is only syntactic sugar to make the code look more like sync code, but as you see in my first example, someMethod will return a Future and if you want to use the string s on the call site, you have to use async/await or then() there.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
In my Service-side, it has huge data and I want to provide items with pagination way.
Is there any recommended flow to traverse with pagination between MediaBrowser/MediaBrowserService(Compat)?
I want to provide partial data in Result<List<MediaItem>> instead of all data (e.g. all YouTube songs), while browser-side using pagination to pull partial data once a time.
In your
MediaService extends MediaBrowserServiceCompat
#Override
public void onLoadChildren(#NonNull final String parentMediaId, #NonNull final Result<List<MediaItem>> result) {
result.detach();
for (int page = 0; i<pages.size(); i++){
result.sendResult(getList(page));
}
}
public List<MediaItem> getList(int page){
//here create List for page-number == page
}
OR
You can make request in your Fragment or Activity with page
MediaBrowserCompat mediaBrowser = ...;
mediaBrowser.subscribe("1"/*it's page*/, mSubscriptionCallback);
then in your Service make this:
#Override
public void onLoadChildren(#NonNull final String page, #NonNull final Result<List<MediaItem>> result) {
result.detach();
result.sendResult(getList(page));
}
I wanted to do a similar thing in my app - I wanted to return the existing songs on the device but in paginated way. Like you say, a partial result in the onLoadChildren() method. I ended up using Android's new Paging library to do just that. Using the library, I could make the client/UI side asks the service for only the pages the user is interested to see, and then serve only those in the onLoadChildren() method, calling the client's subscribe() method to retrieve it.
I go over it in details in a post I wrote, where I also give code samples to better demonstrate the concept.