I am working on an app that serves as a thin client. The app will be in constant TCP connection with a server and the amount of data flowing between them will be very small, only textual.
How should I handle the data, considering this is a typical scenario:
App is started, establish TCP connection to server
The server sends some data, save this data and display them in a ListView
User interacts with the app, server will asynchronously send data, it should be appended to the ListView
I was thinking there might be the main activity havin a member List where it would store the objects to show in the ListView. Upon (asynchronously) receiving some new data, the main thread would be notified and it would reflect the changes on the ListView.
Is there a better, cleaner way? Implementing a contentprovider and using a Loader seems a bit too much, considering I really don't need the data to persist.
You can create your own application extending android.app.Application and your List will be an attribute of your application.
Then using the Context into your AsyncTask you can add the content get asynchronously into your List.
Finally a nice way to update the ListView could be to register your ListActivity as a Listener of all changes of the List content. For example implementing :
public interface IListChangeListener {
public void onContentChange();
}
For each modifications of the List content your application will loop on all the listeners to invoke onContentChange();
On your list activity you will have to implement :
public void onContentChange(){
// Reload the list adapter content and all the notifyDataSetChanged here
}
Don't forget to deregister the ListActivity as listener when it will be destroyed...
Related
In my app I get some data from server in json. Then I fetch fields from json and fill my RecyclerView list with custom adapter. This list is filled with data about jobs. When I click on a job of my recyclerView I move from hosting fragment to dialogfragment for viewing it. This dialogFragment contains homesUp button after pressing which I return to hosting activity. At this dialogFragment I have button which send request to server about this job for adding it to another DB at server.
But when I press this button and send request to the server then after returning to hosting activity I see that data of selected isn't changed. I have several ways of solving this problem:
Add to my Singleton class variable of ArrayList which will be filled by data of shown job and then I will check whether my Arraylist from Singleton contains this id
another method - notifyItemChanged()
All these methods don't work because my list is filled by old data and I only dismiss dialogFragment and return to fragment which contains the list with old data.
Only one way - send request to server for filling the list again.
So, I need your help or useful advice :)
You need to broadcast changed data from dialog fragment to previous screen. For doing this can use LocalBroadcastManager or rxjava or even live data.
Or create a pagedlistadapter from paging library released in android architecture complement and load data directly from query.
Reference: https://developer.android.com/topic/libraries/architecture/paging
I have another one question about transfering data from Activity to Fragment.
In my activity I have next situation: one part of UI is situated in Activity, and another (more dynamic part) is situated in Fragment.
The data which I need to populate my UI elements in Activity and Fragment is on server. To get that data, I am sending request to
server in Acvitity's onCreate() method. In Activity's callback method: void onDataLoaded(List<MyObject> dataList) I get data from server.
And in this method I am creating my Fragment and setup data to it. I am passing data to it through the Bundle object duding creation. Everything
is ok with this. But the issue is in next: on network reconnect I need to load data from server to be sure that all data is up to date. And of course I
need to reinitialize data in Activity and Fragment. But I don't want to fully RE-CREATE fragment. I want just to setup new data to it's fields.
How can I do that properly? Is it a good way to to keep reference in my Activity to that Fragment and call some public method: myFragment.SetMyCustomData(List<MyObject> dataList) ?
I understand that the best way to load data from server in my fragments onCreate() method, but I can't split it into two API calls and I need that data in Activity as well.
Thanks.
Well this is not a transfering problem . Anyway you can use Event Bus for easier communication from Activity to Fragment and vice-versa. It is very easy to use . And as for your problem I belive you are not doing what you need in the right time .
https://github.com/greenrobot/EventBus
I'm developing an application for Android API8.
This application is essentially 4 'pages' of choices (simply a ListView) and a final page with a web page that depends on the previous choices: every page is a list of items returned by a webservice request, queried by a specific query formed by an URL+parameters (REST POST).
My initial idea is to have some activities that access to a common Protocol class: this class has some public members (GetPage1Items(), GetPage2Items(), ..) each of them creates an appropriate URL and runs a common SendRequest() function that sends and receives the HTTP data. This function could be based on a AsyncTask implementation.
Main activity should call one of the public Protocol function and wait for a reply with a ProgressDialog.
My problems are:
- how to notify to the activity that the data is ready in the Protocol class?
- how to have a common Protocol class for all the activities? (I should pass the class to every activity..)
Or better to have a ProtocolBase abstract class with the common HTTP protocol routines and a set of overridable functions to implement each different request (for Page1, Page2, ...). Each activity should implement a specialized ProtocolBase class. BTW I should keep an initial token that I need to include in every request: how can i handle it (static)? and, again, how to notify the data ready?
Maybe inside the onPostExecute() I should access to the ListView passing data to its Adapter?
Thanks
Create a common AsyncTask class and define a Interface and let your activities implement that interfaces, and in onpostexecute of asynctask we will do a call back to the interface method, for reference Check this link
Hope it helps!!!
I'm storing numerical data (streamed from a Bluetooth connection running as a background Service) on a static ArrayList.
Every time my List is modified, I need to update my UI accordingly (which is a plot on an Activity).
I've read about:
Implementing the Observer pattern interface
Using Loaders
Which solution is the most appropriate? Is there any other better/simpler solution?
I would set an android.widget.Adapter (perhaps a BaseAdapter or ListAdapter depending on your data) for the view to provide the data to the view. When the data is updated, simply call the adapter's notifyDataSetChanged() method to update the view.
I have a List of items that I want in a ListView, and I can make it work with setting a custom adapter every time the List grows, but the program flow is kind of weird and I have problems with persistence. (If I switch tabs, the UI gets rebuilt with an empty ListView.)
Now, in my day job I'm a C# developer, so when I look at this problem I see a WPF ListView bound to an ObservableCollection. Does Android/Java have something like that, a "fire and forget" connection between a UI element and a data structure?
You don't need to replace the adapter every time you change the data. The adapter "adapts" between data and view. There is no need to change the adapter as long as the way it adapts does not change.
Activity / Fragment lifecycle is not necessarily the lifecycle of your data collection. You can for example make a singleton data collection somewhere and use an adapter to display that collection all the time. Call .notifyDataSetChanged() on the adapter if you changed the data.
A persistent data collection in Android is probably best backed by a database. Take a look at LoaderManager & ContentProvider to provide and load data then displayed via CursorAdapter.
There is no automatic way of keeping a bunch of data available outside of your Activity / Fragment / .. lifecycle and it can get quite complicated but that's basically what you have to do if you want to keep data for longer than a given lifecycle. Singletons, Activity#onSaveInstanceState(), Activity#getLastNonConfigurationInstance(), Fragment#setRetainInstance(), ... are useful utilities to keep data in memory, databases are good for persistent data.
You have to do a little bit work yourself but it's possible. Use a ContentProvider as your DataSource. How the data is stored is up to you. I would prefer a SQLite-DB. A content provider has the possibility to add ContentObservers. (See this related question.)
You can write a CourserAdapter to fetch the Data from your content provider. And your ContentObserver should call notifyDataSetChanged() on your adapter. This closes the circle and your UI refreshes itself.
In Addition to zapls answer:
You can also write an adapter which contains a BroadcastReceiver. When your DataSource changes you can send a LocalBroadcast. The broadcast handler just calls notifyDataSetChanged() of your adapter. I think this would work around most of the lifecycle problems because only active elements will get the broadcast.
The google documentation has an example for such a solution.