PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label android-asynctask. Show all posts
Showing posts with label android-asynctask. Show all posts

Saturday, July 30, 2022

[FIXED] How to load multiple image in AsyncTask

 July 30, 2022     android, android-asynctask, image     No comments   

Issue

i want to load multiple images by passing a url. unlike this tutorial http://www.learn2crack.com/2014/06/android-load-image-from-internet.html in which only one image is downloaded and is viewed using img.setImageBitmap(image); My question is how can i do to send url to a method to load an image for that url and the method return an image and then i show it in an imageview. then i pass some other url to it and get image in response and i show it in some other imageview.


Solution

Ok assuming then you for some reason want to fetch the images one by one and in sequence, as opposed to in parallel, and assuming you have your URLs in a list, array etc, modify the tutorial example so that onPostExecute calls a method in your activity, either defined in a callback interface or on your class itself, and for each iteration pick one element from the list and start a new LoadImage job whenever the previous one is complete.

Example (untested) code:

public class MainActivity extends Activity {
  Button load_img;
  ImageView img;
  Bitmap bitmap;
  ProgressDialog pDialog;
  private List<String> mURLs = new LinkedList<String>();
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    load_img = (Button)findViewById(R.id.load);
    img = (ImageView)findViewById(R.id.img);
    load_img.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View arg0) {
        // TODO Auto-generated method stub
         mURLs.add("http://www.learn2crack.com/wp-content/uploads/2014/04/node-cover-720x340.png");
         mURLs.add("some-other-URL");

         loadNext();
      }
    });

    private void loadNext() {
        String url = mURLs.remove();
        if (url != null) {
            new LoadImage().execute(url);
        }
    }
  }
  private class LoadImage extends AsyncTask<String, String, Bitmap> {
    @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(MainActivity.this);
            pDialog.setMessage("Loading Image ....");
            pDialog.show();
    }
       protected Bitmap doInBackground(String... args) {
         try {
               bitmap = BitmapFactory.decodeStream((InputStream)new URL(args[0]).getContent());
        } catch (Exception e) {
              e.printStackTrace();
        }
      return bitmap;
       }
       protected void onPostExecute(Bitmap image) {
         if(image != null){
           img.setImageBitmap(image);
           pDialog.dismiss();
         }else{
           pDialog.dismiss();
           Toast.makeText(MainActivity.this, "Image Does Not exist or Network Error", Toast.LENGTH_SHORT).show();
         }

         loadNext();
       }
   }
}

In this example I set the image onto the same ImageView repeatedly which obviously makes no sense. You obviously have to keep track of which image goes onto which imageview by either sending the imageview as an argument to the task, or keep the imageviews (or their R.id.xxx ID's and call findById accordingly) in an array as well, or keep a counter, or.... There are a million ways to solve this.

Another approach is to send the array to the AsyncTask and have doInBackground simply loop over the array with a for-loop or similar.

Note however that a better approach might be to actually parallelize the tasks so that you make sure to utilize your available network bandwidth fully to fetch the images in parallel.



Answered By - JHH
Answer Checked By - Candace Johnson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, May 19, 2022

[FIXED] How can convert AsyncTask to Retrofit for get data from WCF Webservice in Android

 May 19, 2022     android, android-asynctask, json, wcf, web-services     No comments   

Issue

I have a WCF webservice that returns SQL Server database data in JSON format, Now i'm using AsyncTask for get this data in Android by this code :

public class FetchInfo extends AsyncTask {

private String year = "94";
private String month = "1";
private String requested_column = "";
private String kodemelli = "";

public FetchInfo(String year, String month,String requested_column, String kodemelli) {
    this.year = year;
    this.month = month;
    this.requested_column = requested_column;
    this.kodemelli = kodemelli;
}
@Override
protected String doInBackground(Object[] params) {
    try {
        System.out.println("guru");
        DefaultHttpClient httpClient=new DefaultHttpClient();

        //Connect to the server
        HttpGet httpGet=new HttpGet("http://SERVERIP:8005/Service1.svc/checkLogin1?year="+year+"&month="+month+"&requested_column="+requested_column+"&kode_melli="+kodemelli);
        //Get the response

        String result = "";
        HttpResponse httpResponse = httpClient.execute(httpGet);
        HttpEntity httpEntity = httpResponse.getEntity();
        InputStream stream=httpEntity.getContent();
        result = convertStreamToString(stream);
        //Convert the stream to readable format
        if (result.contains("\"error\"") || result.contains("\"server error\"")){
            Main.result = "0";
            MainFish.result = "0";
        }else {
            Main.result = result;
            MainFish.result = result;
        }

    } catch (Exception e) {
        Main.result = "error";
        MainFish.result = "error";
    }

    return "";
}
public static String convertStreamToString(InputStream is)
{
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();

    String line = null;
    try {
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    finally {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return sb.toString();
}
}

By this ,when the requests is more than for example 10 request, the response time is very long. From this topic How to speed up fetching of data from server using JSON? I realized that I should to use Retrofit instead AsyncTask to make my program work.

Now my question is how can convert AsyncTask class to a Retrofit?


Solution

Ok so first you will not use an async task with retrofit. Retrofit takes care of the async part. First you need do define a rest adapter.

Here is a default rest adapter with your parameters in it.

public class ApiClient {

private static ApiInterface sApiInterface;

public static ApiInterface getApiClient(Context context) {

//build the rest adapter
if (sApiInterface == null) {
    final RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint("http://SERVERIP:8005")
            .build();
    sApiInterface = restAdapter.create(ApiInterface.class);
}
return sApiInterface;
}


public interface ApiInterface {
// /Service1.svc/checkLogin1?year="+year+"&month="+month+"&requested_column="+requested_column+"&kode_melli="+kodemelli
@GET("/Service1.svc/checkLogin1")
void getYourObject(
    @Query("year") String year,       
    @Query("month") String month,    
    @Query("requested_column") String requested_column,
    @Query("kode_melli") String kodemelli,
    RetrofitCallback<YourObjectModel> callback);

}

After you have a rest adapter you need a model to put the data in. Use jsonschema2pojo to convert valid JSON to a POJO model. Here is an example of one of my json responses and its model.

{
"id": "37",
"title": "",
"short_name": "",
"short_description": "",
"full_description": "",
"url": "http:\/\/\/shows\/programname",
"Image": {
    "url": "https:\/\/s3.amazonaws.com\/image\/original\/b2mWDPX.jpg",
    "url_sm": "https:\/\/s3.amazonaws.com\/image\/small\/b2mWDPX.jpg",
},
"image": "b2mWDPX.jpg",
"hosts": [{
    "id": "651",
    "display_name": "",
    "username": "",
    "Image": {
        "url": "https:\/\/s3.amazonaws.com\/image\/original\/selfie.jpg",
        "url_sm": "https:\/\/s3.amazonaws.com\/image\/small\/selfie.jpg",
    }
}],
"airtimes": [{
    "start": "11:00:00",
    "end": "13:30:00",
    "weekday": "6"
}],
"categories": [{
    "id": "84",
    "title": "Bluegrass",
    "short_name": "bluegrass"
}],
"meta": []
}

I get this model. And a few others to go with it.

public class Program {
@Expose
private doublea.models.Airtime Airtime;
@Expose
private String id;
@Expose
private String title;
@SerializedName("short_name")
@Expose
private String shortName;
@SerializedName("full_description")
@Expose
private String fullDescription;
@SerializedName("short_description")
@Expose
private String shortDescription;
@Expose
private doublea.models.Image Image;
@SerializedName("image")
@Expose
private String imageName;
@Expose
private List<Host> hosts = new ArrayList<Host>();
@Expose
private List<Category> categories = new ArrayList<Category>();
@Expose
private List<Airtime> airtimes = new ArrayList<Airtime>();

/** Getters and Setters */

public Program() {
}

Then make sure you take care of failure cases.

public class RetrofitCallback<S> implements Callback<S> {
private static final String TAG = RetrofitCallback.class.getSimpleName();


@Override
public void success(S s, Response response) {

}

@Override
public void failure(RetrofitError error) {
    Log.e(TAG, "Failed to make http request for: " + error.getUrl());
    Response errorResponse = error.getResponse();
    if (errorResponse != null) {
        Log.e(TAG, errorResponse.getReason());
        if (errorResponse.getStatus() == 500) {
            Log.e(TAG, "Handle Server Errors Here");
        }
    }
}
}

And finally making the api call.

private void executeProgramApiCall(String year, String month, String requested_column, String kodemelli) {
ApiClient.getApiClient(this).getProgram(year, month, requested_column, kodemelli, new RetrofitCallback<Program>() {

    @Override
    public void success(YourObjectModel program, Response response) {
        super.success(YourObjectModel , response);
        //TODO: Do something here with your ObjectMadel
    }
});
}

I would highly recommend taking a look at the retrofit documentation in case you need anything special like headers or request interceptors.



Answered By - doubleA
Answer Checked By - Robin (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing