I want to WorkManager startWork() to be called every time the user connects to the internet through wifi or 3g/4g/5g.
It calls only one time at the start where I register it.
enqueuing work when a user signs in.
Worker.startWorkManager(SignInActivity.this);
startActivity(new Intent(SignInActivity.this,UsersActivity.class);
it never calls again whenever the user turns Wifi OFF and ON again regardless app is in foreground or background or app is killed through swiped from recent apps.
I want it to be called every time user turned Wifi OFF and ON in every scenario i.e foreground, background, or app is killed.
Worker.class
public class Worker {
public Worker(Context context, WorkerParameters workerParams) {
}
public static void startWorkManager(Context context) {
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
WorkManager.getInstance(context).enqueueUniqueWork(Constants.TAG_SYNC_DATA, ExistingWorkPolicy.KEEP, new OneTimeWorkRequest.Builder(SyncDataWorker.class)
.addTag(Constants.TAG_SYNC_DATA)
.setConstraints(constraints)
.build());
}
}
SyncDataWorker.class
public class SyncDataWorker extends ListenableWorker {
public SyncDataWorker(
#NonNull Context context,
#NonNull WorkerParameters params) {
super(context, params);
}
#NonNull
#Override
public ListenableFuture<Result> startWork() {
return CallbackToFutureAdapter.getFuture(completer -> {
AsyncCallback callback = new AsyncCallback() {
#Override
public void onFailure(Exception e) {
completer.setException(e);
}
#Override
public void onSuccess() {
completer.set(Result.success());
}
#Override
public void onRetry() {
completer.set(Result.retry());
}
};
new AsyncSyncData(getApplicationContext(), callback).execute();
return callback;
});
}
}
AsyncSynData.class
public class AsyncSyncData extends AsyncTask<Void, Void, Void> {
private final Context context;
ArrayList<message> messageArrayListNotSync;
ArrayList<unread_messages> unreadMessagesArrayList;
String user_id = "";
private AsyncCallback callback = null;
public AsyncSyncData(Context context, AsyncCallback callback) {
this.context = context;
messageArrayListNotSync = new ArrayList<>();
unreadMessagesArrayList = new ArrayList<>();
this.callback = callback;
}
#Override
protected Void doInBackground(Void... voids) {
AppDatabase db = AppDatabase.getAppDatabase(context);
user user = null;
ArrayList<user> userArrayList = new ArrayList<>(db.applicationDao().getAllUsers());
if (userArrayList.size() > 0) {
user = userArrayList.get(0);
}
messageArrayListNotSync = new ArrayList<>(db.applicationDao().getAllMessagesNotSync(!user_id.isEmpty() ? user_id : user.threadId));
unreadMessagesArrayList = new ArrayList<>(db.applicationDao().getUnreadMessageStatus());
System.out.println("messageArrayListNotSync: " + messageArrayListNotSync);
System.out.println("unreadMessagesArrayList: " + unreadMessagesArrayList);
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("user_id", !user_id.isEmpty() ? user_id : user.threadId);
Gson gson = new GsonBuilder().create();
JsonArray json_messages = gson.toJsonTree(messageArrayListNotSync).getAsJsonArray();
JsonArray json_unread_messages = gson.toJsonTree(unreadMessagesArrayList).getAsJsonArray();
jsonObject.put("messages", json_messages);
jsonObject.put("unread_messages", json_unread_messages);
RequestHandler.postRequest("/messages", jsonObject, context, new VolleyCallback() {
#Override
public void onSuccess(JSONObject result) {
final JSONObject finalResult = result;
try {
if (result != null && result.has("success") && result.getBoolean("success")) {
new AsyncDeleteUnreadMessagesList(context, unreadMessagesArrayList, new Callback() {
#Override
public void onCallbackCompleted() {
try {
ArrayList<com.app.amber.internet.DATABASE_OPERATIONS.schema.message> messagesToStore = new ArrayList<>();
JSONObject result = finalResult.getJSONObject("data");
JSONObject last_messages = result.getJSONObject("last_messages");
new AsyncUpdateLastMessage(context, last_messages, true, new Callback() {
#Override
public void onCallbackCompleted() {
try {
JSONArray json_messages_to_store = result.getJSONArray("messages");
JSONArray json_evetns_type_1 = result.getJSONArray("eventsType1");
JSONArray json_evetns_type_2 = result.getJSONArray("eventsType2");
for (int i = 0; i < json_messages_to_store.length(); i++) {
JSONObject data = json_messages_to_store.getJSONObject(i);
String id = data.getString("id"),
sender_id = data.getString("sender_id"),
receiver_id = data.getString("receiver_id"),
msg = data.getString("msg"),
type = data.getString("type"),
path = data.getString("path"),
download_status = data.getString("download"),
group_users = data.getString("group_users"),
group_message_status = data.getString("group_message_status");
boolean is_sender = false;
long data_created = data.getLong("date_created");
int is_read = 0;
com.app.amber.internet.DATABASE_OPERATIONS.schema.message message =
new com.app.amber.internet.DATABASE_OPERATIONS.schema.message(id, sender_id, receiver_id, msg, type, path, is_sender, data_created,
is_read, download_status, sender_id, group_users, group_message_status);
messagesToStore.add(message);
}
ArrayList<String> messageIdsType1 = new ArrayList<>();
ArrayList<String> messageIdsType2 = new ArrayList<>();
for (int i = 0; i < json_evetns_type_1.length(); i++) {
messageIdsType1.add(json_evetns_type_1.getJSONObject(i).getString("id"));
}
for (int i = 0; i < json_evetns_type_2.length(); i++) {
messageIdsType2.add(json_evetns_type_2.getJSONObject(i).getString("id"));
}
new AsyncStoreOldMessagesLocally(context, messagesToStore, new Callback() {
#Override
public void onCallbackCompleted() {
new AsyncUpdateMessageStatus(context, messageIdsType1, 1, new Callback() {
#Override
public void onCallbackCompleted() {
new AsyncUpdateMessageStatus(context, messageIdsType2, 2, new Callback() {
#Override
public void onCallbackCompleted() {
new AsyncUpdateMessageStatusList(context, messageArrayListNotSync, new Callback() {
#Override
public void onCallbackCompleted() {
sendCallBack();
}
}).execute();
}
}).execute();
}
}).execute();
}
}).execute();
} catch (Exception e) {
System.out.println("Exception occurred while getting data from data JSONObject received from service: " + e.toString());
e.printStackTrace();
sendCallBack();
}
}
}).execute();
} catch (Exception e) {
System.out.println("Exception occurred while parsing data JSONObject received from service: " + e.toString());
e.printStackTrace();
sendCallBack();
}
}
}).execute();
} else {
sendCallBack();
}
} catch (Exception e) {
System.out.println("Exception occurred while parsing webservice result: " + e.toString());
sendCallBack();
}
}
});
} catch (Exception e) {
System.out.println("exception occurred while parsing messaging lists: " + e.toString());
sendCallBack();
}
return null;
}
private void sendCallBack() {
if (callback != null) {
callback.onSuccess();
}
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
"WorkManager startWork() never calls when constraints are met"
"It calls only one time at the start where I register it."
The ListenableWorker can be recreated in some situations, a new instance of ListenableWorker with the same first ListenableWorker.id. But for it be recreated, it can't be finished. Here are some situations:
Some of the constraints do not matches anymore and it matches again
System was rebooted
Now here are some situations where it will be finished:
Some Exception was raised without treatment
completer.set(Result.success()) was called
completer.set(Result.failure()) was called
There are some situations in your code that the worker can be finished.
There are lots of calls to AsyncSyncData.sendCallBack, which can causes the call of completer.set(Result.success()) on the ListenableWorker instance. If it happens the ListenableWorker completes the job, so it will not be recreated anymore.
"I want to WorkManager startWork() to be called every time the user connects to the internet through wifi or 3g/4g/5g."
The WorkManager alone won't create a new instance of the ListenableWork every time the user connects to Internet. The WorkManager is a API to schedule tasks, and the constraints defined in the ListenableWork are used to not start it while them are not matched, after the ListenableWork finishes, how was discussed above, this task is finished, so no more to do.
If you want to listen to some connectivity changes, you should use ConnectivityManager.registerNetworkCallback and then when the user connects to, you do what you want. Here are some examples that could help you
to do it.
Related
Hello My app is freezes ui for some seconds while it is fetching data from network and stores it in db and then shows it in recyclerview. For fetching data from network I am using retrofit and for storing it and fetching form db Room library. Both with the help of MVVM pattern. Is there a way to remoove the UI freeze?
Here is my code:
In the Mainactivity when clicking download btn
downloadBtn.setOnClickListener(v ->
eventsViewModel.insertEvents(this));
Viewmodel class:
public void insertEvents(Context context){
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String token = preferences.getString("token", "");
final Map<String,String> queryData = new HashMap<>();
queryData.put("token", token);
Call<EventsResponse> call = RetrofitClient.getmInstance().getApi().getEvents(queryData);
call.enqueue(new Callback<EventsResponse>() {
#Override
public void onResponse(Call<EventsResponse> call, Response<EventsResponse> response) {
if (response.code() == 401){
String email = preferences.getString("email", "");
String password = preferences.getString("password", "");
Call<LoginResponse> call1 = RetrofitClient.getmInstance().getApi().loginuser(email, password);
call1.enqueue(new Callback<LoginResponse>() {
#Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
if (response.code() == 200){
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context); // 0 - for private mode
SharedPreferences.Editor editor = pref.edit();
editor.putString("token", response.body().getToken());
editor.apply();
insertEvents(context);
}
else {
}
}
#Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
}
});
}
if (response.code() == 200){
eventList = response.body().getData();
EventsTable eventsTable = new EventsTable();
TicketDatesTable ticketDatesTable = new TicketDatesTable();
for (int i = 0; i < eventList.size(); i++) {
eventsTable.setEvent_id(eventList.get(i).getId());
eventsTable.setTitle_tk(eventList.get(i).getTitle_tk());
eventsTable.setTitle_ru(eventList.get(i).getTitle_ru());
eventsTable.setImageURL("https://bilettm.com/" + eventList.get(i).getImage_url());
eventsTable.setStart_date(eventList.get(i).getStart_date());
eventsTable.setEnd_date(eventList.get(i).getEnd_date());
eventsTable.setSales_volume(eventList.get(i).getEnd_date());
eventsTable.setOrganiser_fees_volume(eventList.get(i).getOrganiser_fees_volume());
eventsTable.setViews(eventList.get(i).getViews());
eventsTable.setSales_volume(eventList.get(i).getSales_volume());
eventsTable.setIs_live(eventList.get(i).getIs_live());
if (!eventList.get(i).getTicket_dates().isEmpty()) {
showTimeList = eventList.get(i).getTicket_dates();
int b = 0;
while (b < showTimeList.size()) {
ticketDatesTable.setEvent_id(showTimeList.get(b).getEvent_id());
ticketDatesTable.setTicket_date(showTimeList.get(b).getTicket_date());
insertTicketDates(ticketDatesTable);
try {
Thread.sleep(150);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
b++;
}
}
insert(eventsTable);
try {
Thread.sleep(150);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
}
#Override
public void onFailure(Call<EventsResponse> call, Throwable t) {
}
});
}
public void insert(EventsTable data){
repository.insertEvents(data);
}
public void insertTicketDates(TicketDatesTable ticketDatesTable){
repository.insertTicketDates(ticketDatesTable);
Here is my repository :
public void insertEvents(EventsTable data){
new EventInsertion(eventsDAO).execute(data);
}
private static class EventInsertion extends AsyncTask<EventsTable, Void, Void> {
private EventsDAO eventsDAO;
private EventInsertion(EventsDAO eventsDAO) {
this.eventsDAO = eventsDAO;
}
#Override
protected Void doInBackground(EventsTable... eventsTables) {
eventsDAO.insertEvents(eventsTables[0]);
return null;
}
}
public void insertTicketDates(TicketDatesTable data){
new TicketDatesInsertion(eventsDAO).execute(data);
}
private static class TicketDatesInsertion extends AsyncTask<TicketDatesTable, Void, Void> {
private EventsDAO eventsDAO;
private TicketDatesInsertion(EventsDAO eventsDAO) {
this.eventsDAO = eventsDAO;
}
#Override
protected Void doInBackground(TicketDatesTable... ticketDatesTables) {
eventsDAO.insertTicketDates(ticketDatesTables[0]);
return null;
}
}
Here is my DAO:
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insertEvents(EventsTable data);
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insertTicketDates(TicketDatesTable datesTable);
I think it freezes when it is storing it into sqlite db
I found my problem. It was initializing entity before starting for loop:
BEFORE:
EventsTable eventsTable = new EventsTable();
for (int i = 0; i < eventList.size(); i++) {
INSERT();
}
AFTER:
for (int i = 0; i < eventList.size(); i++) {
EventsTable eventsTable = new EventsTable();
INSERT();
}
A better solution would be to collect all your required objects in an ArrayList and then pass it on to the AsyncTask and from there to DAO for bulk insertion.
And remove all Thread.sleep(150) statements as they serve no purpose.
why you are using this Thread.sleep(150);Call is already a background task in retrofit
PostData.java
public class PostData {
List<String> gobalAr=new ArrayList<String>();
public List<String> getList(){
return gobalAr;
}
public void setList( List<String> gl){
this.gobalAr = gl;
}
String url = "http://btownmedia.com/";
ArrayList<Post> postArry = new ArrayList();
public List<String> bankin = new ArrayList<String>();
public void getRetrofitPostHospitalObject() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitObjectAPI service = retrofit.create(RetrofitObjectAPI.class);
Call<PostArtical> call = service.getPostHospitalDetails();
call.enqueue(new Callback<PostArtical>() {
#Override
public void onResponse(Response<PostArtical> response, Retrofit retrofit) {
try {
List<Post> PostData = response.body().getPosts();
for (int i = 0; i < PostData.size(); i++) {
Post p = new Post();
p.setId(PostData.get(i).getId());
p.setTitle(PostData.get(i).getTitle());
p.setExcerpt(PostData.get(i).getExcerpt());
p.setThumbnail(PostData.get(i).getThumbnail());
postArry.add(p);
}
gobalAr=new ArrayList<String>();
for (int i = 0; i < postArry.size(); i++) {
Post c = new Post();
c=postArry.get(i);
gobalAr.add(c.getTitle());
}
setList(gobalAr);
Log.d("valuein",gobalAr.toString()); //[Birtamode Eye Hospital (P) Ltd., Birta City Hospital, Life Line Hospital]
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable t) {
Log.d("onFailure", t.toString());
}
});
Log.d("valueout",gobalAr.toString()); // null
}}
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PostData postData = new PostData();
postData.getRetrofitPostHospitalObject();
List<String> list = postData.getList();
Log.d("On", list.toString()); //null
}}
When I am Trying to access Data which From PostData class of method getRetrofitPostHospitalObject() variable "List gobalAr " in MainActivity when i call it is showing null value in gobalAr, Where as I have insert Data from of gobalArr in which add getRetrofitPostHospitalObject(), Please can Help..
Actually i want to access data "gobalAr" variable of PostData class to an MainActivity.
create get() method for List,like this
public List<String> getList(){
return *****;
}
Easy solution call this method in MainActivity
public void getRetrofitPostHospitalObject() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitObjectAPI service = retrofit.create(RetrofitObjectAPI.class);
Call<PostArtical> call = service.getPostHospitalDetails();
call.enqueue(new Callback<PostArtical>() {
#Override
public void onResponse(Response<PostArtical> response, Retrofit retrofit) {
try {
List<Post> PostData = response.body().getPosts();
for (int i = 0; i < PostData.size(); i++) {
Post p = new Post();
p.setId(PostData.get(i).getId());
p.setTitle(PostData.get(i).getTitle());
p.setExcerpt(PostData.get(i).getExcerpt());
p.setThumbnail(PostData.get(i).getThumbnail());
postArry.add(p);
}
gobalAr=new ArrayList<String>();
for (int i = 0; i < postArry.size(); i++) {
Post c = new Post();
c=postArry.get(i);
gobalAr.add(c.getTitle());
}
setList(gobalAr);
Log.d("valuein",gobalAr.toString()); //[Birtamode Eye Hospital (P) Ltd., Birta City Hospital, Life Line Hospital]
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable t) {
Log.d("onFailure", t.toString());
}
});
Log.d("valueout",gobalAr.toString()); // null
}
Then do the rest inside. problem solved
I have a method which fetches the contacts from phone and send this to the php server for processing then it will return data so that it will update in the sql lite DB. I need to run this method continuously on background. I am using Volley for network operation. I am using Handler inside service to run this method. The problem is i am seen too many skipping frames and app is very slow and stucks. I want to run this method without disturbing the main thread. The service code is mentioned below.
public class serv extends Service {
ArrayList<String> aa= new ArrayList<>();
ArrayList<String> bb= new ArrayList<>();
JSONObject JSONimdb;
JSONObject EverythingJSON;
ArrayList<mobstat> musers = new ArrayList<mobstat>();
private RequestQueue requestQueue;
String l;
private static Timer timer = new Timer();
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("Shiva","Service Killed");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
//nonstop1();
threadcheck();
return Service.START_STICKY;
}
private void _startService()
{
long UPDATE_INTERVAL = 5 * 1000;
timer.scheduleAtFixedRate(
new TimerTask()
{
public void run()
{
try
{
getNumber(serv.this.getContentResolver());
} catch (JSONException e)
{
e.printStackTrace();
}
}
}, 1000, UPDATE_INTERVAL);
}
private void nonstop1()
{
final Handler handlera = new Handler();
Runnable updatea = new Runnable()
{
#Override
public void run()
{
try {
getNumber(serv.this.getContentResolver());
} catch (JSONException e) {
e.printStackTrace();
}
handlera.postDelayed(this , 1000);
}
};
handlera.postDelayed(updatea, 10);
}
private void threadcheck()
{
new Thread() {
public void run() {
try {
Log.e("Shiva","Threadcheck");
getNumber(serv.this.getContentResolver());
} catch (JSONException e) {
e.printStackTrace();
}
}
}.start();
}
#Override
public void onDestroy()
{
super.onDestroy();
// Intent broadcatIntent = new Intent("com.statmob.findnum");
//sendBroadcast(broadcatIntent);
//stoptimertask();
//nonstop1();
threadcheck();
}
public void getNumber(ContentResolver cr) throws JSONException
{
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext())
{
String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (phoneNumber.length()>=10)
{
l = phoneNumber.substring(phoneNumber.length()-10);
aa.add(l);
bb.add(name);}
}
phones.close();
JSONimdb = new JSONObject();
for (int i = 0; i < aa.size(); i++)
{
try
{
JSONimdb.put(bb.get(i), aa.get(i));
} catch (JSONException e)
{
e.printStackTrace();
}
}
EverythingJSON = new JSONObject();
try
{
EverythingJSON.put("imdblist", JSONimdb);
} catch (JSONException e)
{
e.printStackTrace();
}
StringRequest stringRequest = new StringRequest(Request.Method.POST, "http://xxxxxxxx/cont.php",
new Response.Listener<String>()
{
#Override
public void onResponse(String s)
{
if (s != null)
{
parseJSONresponse(s);
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
Log.e("Shiva",""+error);
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError
{
Map<String, String> params = new Hashtable<String, String>();
params.put("arr", EverythingJSON.toString());
return params;
}
};
int socketTimeout = 50000;
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
if(requestQueue==null)
{
requestQueue = Volley.newRequestQueue(serv.this);}
stringRequest.setRetryPolicy(policy);
requestQueue.add(stringRequest);
}
private void parseJSONresponse(String s)
{
try
{
JSONArray json = new JSONArray(s);
for (int i = 0; i < json.length(); i++)
{
JSONObject e = json.getJSONObject(i);
musers.add(new mobstat(e.getString("name"), e.getString("status"),e.getLong("time")));
SugarRecord.updateInTx(musers);
}
} catch (JSONException e)
{
e.printStackTrace();
}
}
}
I have tried Timer & Handler, these are working fine but the it makes app slow and not responding. Thread is not working. Please suggest some better way to run this method in background without any disturb to main thread.
create separate process for your service in manifest file might this help you
<manifest>
....
<application>
.....
<service android:name=".serv" android:process=":myprocess" >
</application>
</manifest>
Have you tried IntentService? It's an easy way of running time-consuming background task.
Modify your current implementation with IntentServices.
By default IntentServices runs in background thread. If using Services it uses main thread by default. Then you need to run a Thread inside service to make that execution block in background.
Go through this and this link for more information
I have an Activity which constructs a RESTManager class (used to make an asynchronous call to the server and return data to the Activity).
However, after I construct my RESTManager and call the server using
//Retrieve data from server
RESTManager m = new RESTManager(this,getApplicationContext());
//Set the data list
m.delegate=this;
m.retrieveRoomData();
the server call does not go through until I turn off bluetooth scanning.
However, I start my bluetooth scan immediately after the RESTManager as such:
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.setBackgroundScanPeriod(1100l);
beaconManager.setBackgroundBetweenScanPeriod(100l);
beaconManager.setForegroundScanPeriod(1100l);
beaconManager.setForegroundBetweenScanPeriod(100l);
//Set the custom BeaconLayout for iBeacons
if (myPref.getBoolean("layoutSet", true)) {
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));
backgroundPowerSaver = new BackgroundPowerSaver(this);
Log.v("Beacon Layout", "Beacon Layout Set");
myPref.edit().putBoolean("layoutSet", false).apply();
myPref.edit().commit();
}
beaconManager.bind(this);
I am not getting any error.
Is there any reason why my AsyncTask from RESTManager would hang from the bluetooth scans?
Relevant code:
RESTManager class
public class RESTManager {
private DateTime lastUpdate = DateTime.now();
public AsyncResponse delegate=null;
private SharedPreferences mPrefs;
private SharedPreferences.Editor preferenceEditor;
private ArrayList<RoomData> roomDataList = new ArrayList<RoomData>();
private ArrayList<MeetingData> meetingDataList = new ArrayList<MeetingData>();
private Activity currentActivity;
private Context context;
public RESTManager(Activity currentActivity, Context context) {
this.currentActivity = currentActivity;
this.context = context;
mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
}
//Todo update meeting data logic
public ArrayList<MeetingData> retrieveMeetingDataFromServer() {
return null;
}
public void retrieveRoomData() {
new CallServerForRoomData().execute();
}
//TODO add timestamping logic.
private class CallServerForRoomData extends AsyncTask<String, Void, String> {
String myJsonData = "";
#Override
protected String doInBackground(String... params) {
//If the data isn't cached, call the server.
if (!mPrefs.contains("RoomData")) {
try {
setupHttpClient();
HttpClient myClient = new HttpClient(RequestMethod.GET, "http://10.184.46.217:9012/v1/rooms", new HttpHeaders(), null, null);
myClient.connect();
HttpResponse mR = myClient.processResponse();
myJsonData = mR.getServerResponseAsString();
System.out.println(myJsonData);
preferenceEditor = mPrefs.edit();
preferenceEditor.putString("RoomData", myJsonData);
preferenceEditor.commit();
setRoomDataList(convertRoomDataJson(myJsonData));
return "server";
} catch (HttpClientException e) {
e.printStackTrace();
}
}
//If it is cached, retrieve the data locally.
else {
setRoomDataList(convertRoomDataJson(mPrefs.getString("RoomData", "NULL")));
return "local";
}
return "Done";
}
protected void onPostExecute(final String result) {
delegate.dataFinishedRetrieving(getRoomDataList());
// setRoomDataList(convertRoomDataJson(myJsonData));
currentActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(context, "Data retrieved on " + result + " storage", Toast.LENGTH_SHORT).show();
}
});
}
}
/**
* AsyncTask for retrieving a room's meeting data.
* Pass in the room's unique identifier as a parameter of the execute method.
*/
//TODO add timestamping logic
private class CallServerForMeetingData extends AsyncTask<String, Void, String> {
String myJsonData = "";
#Override
protected String doInBackground(String... params) {
try {
setupHttpClient();
HttpClient myClient = new HttpClient(RequestMethod.GET, "http://10.184.146.217:9012/v1/room/" + params[0] + "/schedule", new HttpHeaders(), null, null);
myClient.connect();
HttpResponse mR = myClient.processResponse();
myJsonData = mR.getServerResponseAsString();
} catch (HttpClientException e) {
e.printStackTrace();
}
//Set the converted MeetingData to the RoomData object
for (RoomData e : roomDataList) {
if (e.getObjectId() == params[0]) {
e.setMeetingData(convertMeetingDataJson(myJsonData));
}
}
return "Done";
}
}
//Initializes the HTTPClient and attaches it to the application lifecycle.
public void setupHttpClient() {
HttpCacheManager.init(Application.getAppContext());
}
public ArrayList<MeetingData> convertMeetingDataJson(String JsonData) {
final Gson gson = initCustomGSON();
Type MeetingDataListType = null;
if (JsonData != "") {
MeetingDataListType = new TypeToken<ArrayList<MeetingData>>() {
}.getType();
}
return (gson.fromJson(JsonData, MeetingDataListType));
}
public ArrayList<RoomData> convertRoomDataJson(String JsonData) {
final Gson gson = initCustomGSON();
Type RoomDataListType = null;
if (!JsonData.equals("")) {
RoomDataListType = new TypeToken<ArrayList<RoomData>>() {
}.getType();
roomDataList = (gson.fromJson(JsonData, RoomDataListType));
}
roomDataList = (gson.fromJson(JsonData, RoomDataListType));
for (RoomData e : roomDataList) {
Log.v("RoomData name", e.getName());
Log.v("RoomData roomId", e.getObjectId());
//Log.v("RoomData imageUrl", e.getImageUrl());
if (e.getBeacons() != null) {
Log.v("Number of beacons", e.getBeacons().toString());
}
}
return roomDataList;
}
/**
* Initializes the GSON Json Decoder with the custom JodaTime serializers.
*
* #return
*/
public Gson initCustomGSON() {
final GsonBuilder builder = new GsonBuilder();
JodaTimeConverters converter = new JodaTimeConverters();
converter.registerAll(builder);
return builder.create();
}
public ArrayList<RoomData> getRoomDataList() {
return roomDataList;
}
public void setRoomDataList(ArrayList<RoomData> roomDataList) {
this.roomDataList = roomDataList;
}
public void setMeetingDataListForRoom(RoomData whichRoom) {
new CallServerForMeetingData().execute(whichRoom.getObjectId());
}
}
I have created a webservice class lokks like below, in with in the "onCreate" method of the service i Have called my webservice which takes around 45 seconds to complete its execution for that time my UI gets black that means it Hangs upto the execution of the web service,
below is the code of my service,
public class productService extends Service
{
private static Context _pctx;
static Vector _productsAll = null;
public static void getInstance(Context context) throws Exception
{
if (_pctx == null)
{
_pctx = context;
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate()
{
try
{
LoadAllProducts();
}
catch (Exception e)
{
e.printStackTrace();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
return START_REDELIVER_INTENT; // 21 sec
}
#Override
public void onDestroy()
{
_productsAll= null;
}
private void LoadAllProducts() throws Exception
{
_productsAll = new Vector();
Exception e = null;
WebResponse myResponse = DataService.GetData("$PR$" , _pctx);
if (Helper.getBoolValueFromString(myResponse.Success))
{
saveMDBData(myResponse.Response);
}
else
{
e = new Exception(myResponse.Response.toString());
}
//cats = null;
if (e != null) {
throw e;
}
}
public static void saveMDBData(StringBuffer pMDBData)
{
Vector Rows;
Vector Cols;
int iRow = 0;
if (pMDBData != null)
{
if (!pMDBData.toString().trim().equals(""))
{
Rows = Helper.getRowsNew(pMDBData);
if (Rows != null)
{
for (iRow = 0; iRow < Rows.size(); iRow++)
{
if (!((String) Rows.elementAt(iRow)).trim().equals(""))
{
Cols = Helper.SplitMultiCharDelimiters((String) Rows.elementAt(iRow), Helper.FIELDDELIMITERS);
assignMDBData(Cols);
}
}
}
}
}
Rows = null;
Cols=null;
}
private static void assignMDBData(Vector pCols)
{
Product myProduct = null;
if (pCols != null)
{
//Create new setting instance
//myProduct = new Product();
myProduct = new Product();
//assign values
myProduct.Id = Helper.getIntValue((String)pCols.elementAt(0));
myProduct.PartNumber = (String)pCols.elementAt(1);
myProduct.Description = (String)pCols.elementAt(2);
myProduct.IdCategory = Helper.getIntValue((String)pCols.elementAt(3));
myProduct.Ideal = Helper.getIntValue((String)pCols.elementAt(4));
myProduct.Taxable = Helper.getBoolValueFromString((String)pCols.elementAt(5));
myProduct.Discountable = Helper.getBoolValueFromString((String)pCols.elementAt(6));
myProduct.LotSize = Helper.getIntValue((String)pCols.elementAt(7));
myProduct.RetailPrice = Helper.getDoubleValue((String)pCols.elementAt(8));
myProduct.ListPrice = Helper.getDoubleValue((String)pCols.elementAt(9));
myProduct.TotalOnHand = Helper.getIntValue((String)pCols.elementAt(10));
myProduct.TotalOnOrder = Helper.getIntValue((String)pCols.elementAt(11));
myProduct.IsPrepack = Helper.getBoolValueFromString((String)pCols.elementAt(12));
//myProduct.Breakdown = (String)pCols.elementAt(13);
myProduct.NoInventory = Helper.getBoolValueFromString((String)pCols.elementAt(13));
myProduct.IsCollection = Helper.getBoolValueFromString((String)pCols.elementAt(14));
myProduct.Followup = Helper.getIntValue((String)pCols.elementAt(15));
myProduct.PctDiscount = Helper.getDoubleValue((String)pCols.elementAt(16));
myProduct.IdGroup = Helper.getIntValue((String)pCols.elementAt(17));
myProduct.Points = Helper.getIntValue((String)pCols.elementAt(18));
myProduct.IsVitamin = Helper.getBoolValueFromString((String)pCols.elementAt(19));
myProduct.PusChange = Helper.getIntValue((String)pCols.elementAt(20));
myProduct.MovedToCloseout = Helper.getDateDataSync((String)pCols.elementAt(21));
myProduct.OnHandDelta = Helper.getIntValue((String)pCols.elementAt(24));
//save processed setting to persistent collection
_productsAll.addElement(myProduct);
//release saved setting in)stance
myProduct = null;
}
}
}
Anyone please help me to sort out the probelm,
I am Stuck Here,
Thanks in Advance!
For Background Services use the AsyncTask which creates background threads so doesn't effect your main UI.
Here is the Code:
public class DownloadData extends AsyncTask<String, String, String> {
#Override
public void onPreExecute() {
// Do Some Task before background thread runs
}
#Override
protected String doInBackground(String... arg0) {
// To Background Task Here
return null;
}
#Override
protected void onProgressUpdate(String... progress) {
// publish progress here
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// Do some Task after Execution
}
}
For more details: See this one
http://developer.android.com/reference/android/os/AsyncTask.html