Calling Async task in a loop? - android

I want to call an Async task in a loop and execute it a few times in parallel.
I have a List of items which I split out into smaller lists with 10 items in each list.
Then for every small List I execute the Async task using THREAD_POOL_EXECUTOR.
Problem is, its not working. I'm thinking its because I use the same list each time when it is passed to the AsyncTask - and I think it may be passed as reference.
Do I need to somehow create new Lists dynamically?
//split the ListItems into 10s
if (actualThumbs.size() > 10){
List<List<ListItem>> parts = chopped(actualThumbs, 10); // this splits it into parts of 10
List< ListItem > listToSend = new ArrayList<ListItem>(); //this is the list to pass
for(int i = 0; i < parts.size(); i++){ //for every part
for(int x = 0; x < parts.get(i).size(); x++){ //for everything in that part
//add to its own List
listToSend.add(parts.get(i).get(x));
}
//this is the async task
loadActualThumbs thumbs = new loadActualThumbs();
//execute multiple threads
thumbs.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,listToSend );
listToSend.clear(); //clearing the list ready for a new one - PROBLEM?
}
}
else
{
//else just execute AsyncTask normally, this works OK
loadActualThumbs thumbs = new loadActualThumbs();
thumbs.execute(actualThumbs);
}
EDIT:
I tried changing my code, to instead add every List that I want to send to the Async task to another List, and then loop through that List of Lists and send each one:
if (actualThumbs.size() > 10){
List<List<ListItem>> parts = chopped(actualThumbs, 10);
List< ListItem > listToSend = new ArrayList<ListItem>();
List<List<ListItem>> sendMe = new ArrayList<List<ListItem>>();
for(int i = 0; i < parts.size(); i++){ //for every part
for(int x = 0; x < parts.get(i).size(); x++){ //for everything in that part
//add to its own ListItem?
listToSend.add(parts.get(i).get(x));
}
sendMe.add(listToSend);// add the List to this List
listToSend.clear();
}
for(int e = 0; e<sendMe.size();e++){ //loop through the list of lists
loadActualThumbs thumbs = new loadActualThumbs();
//execute multiple threads?
thumbs.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,sendMe.get(e) ); // execute async with correct List
}
}
else
{
if (actualThumbs.size() > 0){
//load actual thumbnails
loadActualThumbs thumbs = new loadActualThumbs();
thumbs.execute(actualThumbs);
}
}

Your code should look like this now :
List<List<ListItem>> parts = chopped(actualThumbs, 10);
for(List<ListItem> list : parts) {
new loadActualThumbs().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, list);
}
I am actually not sure what size the threadpool is or if it's a cached thread pool, but you can create your own threadpool with Executors.newCachedThreadPool() and Executors.newFixedThreadPool(int count)... but I'd just go with the AsyncTask.THREAD_POOL_EXECUTOR....should work :)

If you need to execute your asynctask for particular interval of time then you may make use of Timer for same ..
Like this ..
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
try {
System.out
.println("=================== I am in pooling state ===============");
GetBookingStatusAsyncTask performBackgroundTask = new GetBookingStatusAsyncTask();
performBackgroundTask.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
};
Now when you need to kill this timer ..
timer.cancel();
timer = null;
Also make use of boolean check so as to avaoid infinite loop .. i.e if true then execute AsyncTask .. and if false then stop AsyncTask .. just like ..
public void callAsynchronousTask(boolean b) {
// timer.cancel();
if (b) {
System.out.println("============= Check for timer check " + tcheck);
// execute in every 10000 ms
tcheck++;
} else {
System.out
.println("============= Check for timer check + cancelling timer task "
+ tcheck);
timer.cancel();
timer = null;
System.out.println("=============timer is ===" + timer);
// finish();
return;
}
}
When you need to close this task then simply of true / false condition pass like ..you need to pass this in your AsyncTask.
callAsynchronousTask(true); / callAsynchronousTask(false);
Hope it helps!..

Related

How to modify the code to have image slideshow in android?

I am trying to make a slideshow of a few images while making an android app. I am using this code below
final int[] array = {R.drawable.cow_1, R.drawable.cow_2, R.drawable.cow_3, R.drawable.cow_4};
for (int i = 0; i < 4; i++){
final int finalI = i;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
animal_image.setImageResource(array[finalI]);
}
}, 4000);
}
The problem I am facing is that I am not getting the slideshow of images one-by-one instead the code is showing the last image after the first one directly. There's some problem with the code, please help me fix it.
Try with below
final int[] array = {R.drawable.cow_1, R.drawable.cow_2, R.drawable.cow_3, R.drawable.cow_4};
for (int i = 0; i < 4; i++){
final int finalI = i;
Thread.sleep(4000);
animal_image.setImageResource(array[finalI]);
}
you have to add try{... }catch(Exception e){} block.
What you code is doing is that it is creating a Handler for each of the image and setting the delay to 4 seconds. The for loop will run instantly for each iteration and all the Handlers that have been created will run after 4 seconds. This causes the last image to show up because the last Handler will have run a few milliseconds after the rest. In order to fix this, you need to have an incremental timer for each Handler.
final int[] array = {R.drawable.cow_1, R.drawable.cow_2, R.drawable.cow_3, R.drawable.cow_4};
for (int i = 0; i < 4; i++){
final int finalI = i;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
animal_image.setImageResource(array[finalI]);
}
}, 4000 * finalI);
}
Using the above given code, the first image will be displayed, and all the other images will be displayed after a multiple of 4 seconds based on the image number (image 2 will be shown after 4 seconds, image 3 will be shown after 8 seconds, image 4 will be shown after 12 seconds and so on).

How wait in a loop to execute a task?

for(int i=0; i < size; i++){
loadImageFromServer(i);
}
The loadImageFromServer(); takes sometime to load image from server .
Example:
when i is 0, loadImageFromServer(0) starts. But then loop executes again before completing the loadImageFromServer(0) and starts loadImageFromServer(1). Now I want the loop to wait for that time(I mean, first complete the task of loadImageFromServer(0)) and then execute the next loop. How to do that ?
As a suggestion, ideally you should download multiple images simultaneously, to do that use ThreadPoolExecutor.
int numberOfProcessor = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
numberOfProcessor * 2,
numberOfProcessor * 2,
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>()
);
for (int i = 0; i < size; i++) {
executor.execute(new Runnable() {
#Override
public void run() {
loadImageFromServer();
}
});
}

Android - Load more data using AsyncTask which gets data from API in RecyclerView

I'm trying to dynamically add items to my RecyclerView.
Basically, I am following Instagram style, especially in the search fragment of Instagram. Currently, my app gets the number of item sent by server (default is 10) and add it onto the number of displayed items on the recyclerview.
I have an interface to get the output from the server, here's the OnLoadMoreListener
System.out.println("OnLoadMore");
list.add(null);
profilTemanAdapter.notifyItemInserted(list.size());
handler.postDelayed(new Runnable() {
#Override
public void run() {
//remove progress item
list.remove(list.size() - 1);
profilTemanAdapter.notifyItemRemoved(list.size());
TimelineFriendListAPI timelineFriendListAPIInput = new TimelineFriendListAPI();
timelineFriendListAPIInput.kevin.query.user_id = userId;
timelineFriendListAPIInput.kevin.query.other_user_id = otherUserId;
timelineFriendListAPIInput.kevin.query.friend_mode = friendMode;
nextFriendList = result.kevin.results.friend_list;
TimelineFriendListAPIFunc timelineFriendListAPIFunc = new TimelineFriendListAPIFunc(BottomProfilTemanFragment.this.getActivity());
timelineFriendListAPIFunc.delegate = BottomProfilTemanFragment.this;
if (nextFriendList.size() == 10) {
counter += 10;
timelineFriendListAPIInput.kevin.query.friend_count = String.valueOf(counter);
Log.d("CounterBefore", String.valueOf(counter));
timelineFriendListAPIFunc.execute(timelineFriendListAPIInput);
Log.d("CounterAfter", String.valueOf(counter));
Log.d("FriendLists", nextFriendList.get(0).friend_alias);
//Refresh Per Item
for (int i = 0; i < 10; i++) {
list.add(nextFriendList.get(i));
profilTemanAdapter.notifyItemInserted(list.size());
Log.d("FriendLists", nextFriendList.get(i).friend_alias);
}
Log.d("FriendLists", nextFriendList.get(10).friend_alias);
Log.d("OnLoadNotifFriendSize10", "size = " + list.size());
profilTemanAdapter.setLoaded();
} else if (nextFriendList.size() < 10 && nextFriendList.size() > 0) {
int friendCounter = nextFriendList.size();
counter += friendCounter;
timelineFriendListAPIInput.kevin.query.friend_count = String.valueOf(counter);
timelineFriendListAPIFunc.execute(timelineFriendListAPIInput);
//Refresh Per Item
for (int i = 0; i < friendCounter; i++) {
list.add(nextFriendList.get(i));
}
profilTemanAdapter.notifyItemInserted(list.size());
profilTemanAdapter.setLoaded();
} else {
}
}
}, 1000);
System.out.println("loadMore");
Here's the Interface function in the same class
result = output; //result is a global variable to be accessed inside the OnLoadMore
//profilTemanAdapter = new ProfilTemanAdapter(list, recyclerView, output);
//createlist();
handler = new Handler();
list = output.kevin.results.friend_list;profilTemanAdapter = new `ProfilTemanAdapter(list, recyclerView, output);`
profilTemanAdapter.setOnLoadMoreListener(profilTemanAdapterHandler);
recyclerView.setAdapter(profilTemanAdapter);
Log.d("FriendLists", list.get(0).friend_alias);
As can be expected, nextFriendList.get(10).friend_alias which is the 11th value in the List, is still the same as nextFriendList.get(0).friend_alias as nextFriendList has not been updated through the interface.
How to display it correctly as in waiting for the AsyncTask to finish, but not using .get() so that it doesn't block UI thread just like Instagram (or any "InfiniteScrolling" app) ?
Small update :
Used ProgressBar in Async so that it loads the information gained from server before displaying, but it messed the layout. There's an EditText above the RecyclerView which gets repeated on every OnLoadMore. Moreover it doesn't look nice with ProgressBar popping up for every information load..
Another update :
I am able to display OnLoadMore items but it replaces the items before the new items.

How to put Json inside asynctask - Android

I have a json function that connects to a database and returns a result. It does this about 15 times or for how many comments there are in the database. The json function is inside a while loop, and repeats itself until all the comments have been taken from the database or until it reached 15 comments. The problem is when the app loads the comments it does it during the onCreate part of the app. I want the app to load and then the json function to load in the back. I know I can do this with an asynctask but I am not familiar with them. So I was hoping someone would be able to tell me how to place this code into a asynctask.
UserFunctions CollectComments = new UserFunctions();
JSONObject json = CollectComments.collectComments(usernameforcomments, offsetNumber);
int commentCycle = 1;
// check for comments
try {
if (json.getString(KEY_SUCCESS) != null) {
registerErrorMsg.setText("");
String res2 = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res2) == 1){
String numberOfComments = json.getString(KEY_NUMBER_OF_COMMENTS);
String offsetNumberDb = db.getOffsetNumber();
int numberOfComments2 = Integer.parseInt(numberOfComments) - Integer.parseInt(offsetNumberDb);
offsetNumber = offsetNumberDb;
//if comment number is less than 15 or equal to 15
if(numberOfComments2 <= 15){
while (commentCycle <= numberOfComments2){
JSONObject json2 = CollectComments.collectComments(usernameforcomments, offsetNumber);
TextView commentView = new TextView(this);
commentView.setText(json2.getString(KEY_COMMENT));
LinearLayout.LayoutParams commentViewParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
commentViewParams.setMargins(20, 10, 20, 20);
commentView.setBackgroundResource(R.drawable.comment_bg);
commentView.setTextColor(getResources().getColor(R.color.black));
commentBox.addView(commentView, commentViewParams);
verify2 = verify2 + 1;
offsetNumber = json2.getString(KEY_OFFSET_NUMBER);
commentCycle = commentCycle + 1;
}//end while
}//end if comment number is less than or equal to 15
}//end if key is == 1
else{
// Error in registration
registerErrorMsg.setText(json.getString(KEY_ERROR_MSG));
}//end else
}//end if
} //end try
catch (JSONException e) {
e.printStackTrace();
}//end catch
All this code works but I want it running in the background not during the apps oncreate some one please try putting this into a asynctask or at least help me understand how to do so.
You should put your while loop in a new Thread or Async Task. Here is how is will work
public class JsonWork extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
//your while loop goes here
}
}
Just before the while loop in your current code you should call new JsonWork().execute(). So that it would execute the while loop in a new AsyncTask Thread.

For Loop reading infinity

I am trying to make a simple screen that shows you the amount of money you have earned by the second, so im trying to create a live feed type textveiw that updates every second with the amount of money you have earned, with my code when it runs on my phone it only reads "infinity" and when i tried to add in a 1 second delay it froze all together, here is the code that i wrote, i am using a for loop because i didnt know of a better way if anyone has a better way of achieving what i am trying to do please let me know..
// Calculate pay per second
double PPS = (HW/3600);
double OTPPS = (OTW/3600);
double HPDPS = (HPD*3600);
double money = 0;
double Reserve = 0;
loc = 0;
// Display
for(int i=0; i<HPDPS & loc!=7; i++)
{
money = (PPS+Reserve);
Reserve = (Reserve+money);
TextView textView = (TextView) this.findViewById(R.id.yourpay);
textView.setText(String.valueOf(money));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Thanks in advance for any help!
======================================================================================
Here is an edited version but i am still having a problem where it just displays infinity on the screen, how do i fix this? or how do i use the timer method?
public void sendMessage(View view) {
// Receive messages from options page
Intent intent = getIntent();
double HW = intent.getDoubleExtra(Options.MESSAGE_HW, 0);
double OTW = intent.getDoubleExtra(Options.MESSAGE_OTW, 0);
double HPD = intent.getDoubleExtra(Options.MESSAGE_HPD, 0);
// Calculate pay per second
double PPS = (HW/3600);
double OTPPS = (OTW/3600);
double HPDPS = (HPD*3600);
double money = 0;
double Reserve = 0;
// Display
for(int i=0; i<HPDPS; i++)
{
money = (PPS+Reserve);
Reserve = (Reserve+money);
TextView textView = (TextView) this.findViewById(R.id.yourpay);
textView.setText(String.valueOf(money));
}
// set textView
}
Better way is to user a Timer and TimerTask.
EDIT:
Here is a sample application code to user Timer and TimerTask:
final TextView t1 = (TextView) findViewById(R.id.textView1);
final Timer t =new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
t1.setText("Hello" + counter++); //Place your text data here
//Place your stopping condition over here. Its important to have a stopping condition or it will go in an infinite loop.
if(counter == 10)
t.cancel();
}
});
}
}, 1000, 1000);
Hope this helps.
[1] You are doing Bitwise ANDing (Bitwise ANDing -> &) here
for(int i=0; i<HPDPS & loc!=7; i++)
^
[2] Your loc in always 0, because you did loc=0 and in for loop loc is never updated
So loc!=7 is ALWAYS TRUE

Categories

Resources