AsyncTask do not work in for loop - android

My AsyncTask class do not work inside for loop. Below is my code please review it.
for (int i = 0; i < size; i++) {
String id = careplan_disease_Parser.DiseaseID.get(i);
String method = "GetCarePlan_Comment?CurrentValue=0&OptionId=" + id + "&DiseaseID=" + id + "&OrgId=" + orgId + "";
String link = "GetCarePlan_Comment_dislink";
task = new AsyncTask123();
task.execute(link, method);
method=null;
link=null;
task=null;
}
Task executes only once. so i can't get value from web service second time in a loop.
Please help me how to make it work.
Thanks

You can write a start-method, that gets called in the onPostExecute-part of you AsyncTask. It should look like this:
private void start(int number)
{
if(number == size)
{
//exit
}
else
{
new AsyncTask123().execute(link, method);
}
}
private class AsyncTask123 extends AsyncTask<> {
protected void onPostExecute() {
start(i++);
}
}
This should work, you just have to fit it for your needs.

if you want AsyncTask in for loop then you should call your class like:
new AsyncTask123().execute(link, method);
Not like :
task = new AsyncTask123();
task.execute(link, method);

Related

Arraylist of strings into one comma separated string

Trying to convert a Arraylist of strings into one big comma separated string.
However when I use the
String joined = TextUtils.join(", ", participants);
Debugger shows me size of 4 for participants however the joined value as "" therefore empty
private ArrayList<String> participants;
Not sure what is going wrong?
UPDATE:
List<String> list = new ArrayList<>();
list.add("Philip");
list.add("Paul Smith");
list.add("Raja");
list.add("Ez");
String s = TextUtils.join(", ", list);
This works when I have a list that I manually populate however below is how the code is working right now.
In the onCreate()
callApi(type);
String s = TextUtils.join(", ", participants);
getSupportActionBar().setTitle(s);
In callAPI():
JSONArray participantsR = sub.getJSONArray("referralParticipants");
Log.e("Participants length ", String.valueOf(participantsR.length()));
for (int i = 0; i < participantsR.length(); i++)
{
JSONObject object = participantsR.getJSONObject(i);
String firstname = (String) object.get("fullName");
participants.add(firstname);
Log.e("Times", String.valueOf(i));
}
I'm trying to reproduce your error and am unable to. Here is my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_temp);
List<String> list = new ArrayList<>();
list.add("Philip Johnson");
list.add("Paul Smith");
list.add("Raja P");
list.add("Ezhu Malai");
String s = TextUtils.join(", ", list);
Log.d(LOGTAG, s);
}
My output is Philip Johnson, Paul Smith, Raja P, Ezhu Malai as expected.
Are you importing the correct TextUtils class?
android.text.TextUtils;
Given the new information, here is my approach:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_temp);
callApi(type, new OnResponseListener<List<String>>() {
#Override public void onResponse(List<String> list) {
getSupportActionBar().setTitle(TextUtils.join(", ", list));
}
});
}
I don't know what networking library you're using, but you may have to define OnResponseListener as an interface. It's very easy:
public interface OnResponseListener<T> {
public void onResponse(T response);
}
You will then need to modify your callApi function to take an instance of OnResponseListener> and call it's onResponse method after completing the call.
I would recommend looking into the Volley library, and reading the Android documentation about simple network calls.
I use StringUtils.join from Apache Common Utilities.
The code is super-simple just the way you wanted,
StringUtils.join(participants,", ");
Works flawlessly for me.
EDIT
As requested, here is the StringUtils.java file for those who just want to use this single utility class and not the entire library.
I don't know what TextUtils does. This will do it.
StringBuffer sb = new StringBuffer();
for (String x : participants) {
sb.append(x);
sb.append(", ");
}
return sb.toString();
Easy enough, just use that.
Try with kotlin
val commaSeperatedString = listOfStringColumn.joinToString { it ->
"\'${it.nameOfStringVariable}\'" }
// output: 'One', 'Two', 'Three', 'Four', 'Five'

android reflection in enhanced for loop

I know some things about reflection because i read this post: call function based on string android
Class c = Class.forName("MyClass");
Method m = c.getMethod("get"+arg);
return (Integer) m.invoke(this);
I am using an enhanced for loop like this:
int check = 0,check2=0;
for(PostValue post : helper.posts)
{
//Name method with a String
if(category.equals(post.getMethodFromStringHere()))
{
check++;
}
}
so what I want is that I can get the method from a string in the if above.
Thanks in advance.
If you need more information you can ask,
EDIT:
try {
int check = 0,check2=0;
Class<?> postValueClass = Class.forName("PackageName.PostValue");
Method m = postValueClass.getMethod("get"+category);
for(PostValue post : helper.posts)
{
String response;
response = (String) m.invoke(post);
if(category.equals(response))
{
check++;
}
Something like that would do the job. i haven't tested it !! You might need to cast some objects.
Class postValueClass = Class.forName("PostValue");
Method getMethodFromStringHereMethod = postValueClass.getMethod("getMethodFromStringHere");
int check = 0;
int check2 = 0;
for(PostValue post : helper.posts)
{
Boolean response = (Boolean) getMethodFromStringHereMethod.invoke(post);
if (response.getBooleanValue())
{
check ++;
}
}

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.

Don't change varriable value after first call

I'm new android/java programmer and I can't find anywhere how to set default varriable value only on first call. My console log delete after second call. My code looks like:
public class Ftp {
[...]
//Console
String console_strings[] = new String [15];
int console_line = 0;
//
[...]
public void drawConsole(String msg){
CharSequence time = DateFormat.format("hh:mm:ss", d.getTime());
String message = "["+time+"] "+msg;
TextView console = (TextView)((Activity)context).findViewById(R.id.console);
String newString = "";
for(int i = 0; i < console_strings.length; i++){
if(console_strings[i] != null)
newString += console_strings[i] + "\n";
else
{
console_strings[i] = message;
newString += console_strings[i] + "\n";
break;
}
}
console.setText(newString);
}
}
Whenever I want to add something to the console, it delete old text value.
There are multiple ways to do this. The problem you are having is that you are setting the entire textview's text at once. You could do one of a few things. You could do
console.setText(console.getText() + newString);
or
console.append(newString);
Both of these would work. There are multiple other ways, but those should do it for you.
TextView has also an append method

How to make threads synchronize in a loop statement?

I am new to threads. I am trying to load a small array of photos. Right now I am using Async tasks/ threads, but how do I make the outcome sequential? Below is an illustration:
What I want:
a[0] = photo1;
a[1] = photo2;
a[2] = photo3;
a[3] = photo4
What my program gives me instead. Note that the order changes and is random:
a[0] = photo[2];
a[1] = photo[1];
a[2] = etc
Here's a snippet of my code:
...
for (int i = 0; i < mNoOfContacts; i++) {
String stringContactUri = storeSettings.getString("contactUri"+i, "");
if (stringContactUri != ""){
Uri contactUri = Uri.parse(stringContactUri);
loadContactInfo(contactUri);
}
...
private void loadContactInfo(Uri contactUri) {
AsyncTask<Uri, Void, ContactInfo> task = new AsyncTask<Uri, Void, ContactInfo>() {
#Override
protected ContactInfo doInBackground(Uri... uris) {
return mContactAccessor.loadContact(getContentResolver(), uris[0]);
}
#Override
protected void onPostExecute(ContactInfo result) {
Contacts[mNoOfContacts] = result;
Toast.makeText(getApplicationContext(), mNoOfContacts+"Picked Contact"+Contacts[mNoOfContacts].getDisplayName(), Toast.LENGTH_SHORT).show();
mNoOfContacts++;
}
};
task.execute(contactUri);
}
...
My code is a modification of the Google Android demo app - Business Cards.
Please help! Thanks!
What might be the easiest thing to do is make the onPostExecute method call a routine that does the sorting: pass both the ContactInfo and the Uri and then compare the Uri with the original and put it in the proper place.
Alternatively modify your AsyncTask so instead of launching one per Uri you launch one you pass all the Uris at once and then go from there.
I would think that, by definition, "Asynchronous Tasks" are not synchronized...Asynchronous literally means "not synchronized." If you want it synchronized, just load them the old fashioned way by doing a URI call, get your photo and do it again once the last photo was loaded.

Categories

Resources