Issue
I'm Working in a project, I'm tring to download images from a folder, I have this code:
private class DownloadTask extends AsyncTask<ArrayList<URL>, Integer, List<Bitmap>> {
// Before the tasks execution
protected void onPreExecute() {
// Display the progress dialog on async task start
mProgressDialog.show();
mProgressDialog.setProgress(0);
}
// Do the task in background/non UI thread
protected List<Bitmap> doInBackground(ArrayList<URL>... urls) {
int count = urls[0].size();
HttpURLConnection connection = null;
List<Bitmap> bitmaps = new ArrayList<>();
// Loop through the urls
for (int i = 0; i < count; i++) {
URL currentURL = urls[0].get(i);
// So download the image from this url
try {
// Initialize a new http url connection
connection = (HttpURLConnection) currentURL.openConnection();
// Connect the http url connection
connection.connect();
// Get the input stream from http url connection
InputStream inputStream = connection.getInputStream();
// Initialize a new BufferedInputStream from InputStream
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
// Convert BufferedInputStream to Bitmap object
Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream);
// Add the bitmap to list
bitmaps.add(bmp);
// Publish the async task progress
// Added 1, because index start from 0
publishProgress((int) (((i + 1) / (float) count) * 100));
if (isCancelled()) {
break;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// Disconnect the http url connection
connection.disconnect();
}
}
// Return bitmap list
return bitmaps;
}
// On progress update
protected void onProgressUpdate(Integer... progress) {
// Update the progress bar
mProgressDialog.setProgress(progress[0]);
}
// On AsyncTask cancelled
protected void onCancelled() {
//Snackbar.make(mCLayout,"Task Cancelled.",Snackbar.LENGTH_LONG).show();
}
// When all async task done
protected void onPostExecute(List<Bitmap> result) {
// Hide the progress dialog
mProgressDialog.dismiss();
// Loop through the bitmap list
for (int i = 0; i < result.size(); i++) {
Bitmap bitmap = result.get(i);
saveToSdCard(bitmap,arrayID.get(i).toString());
}
}
}
// Custom method to convert string to url
protected URL stringToURL(String urlString) {
try {
URL url = new URL(urlString);
return url;
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public static String saveToSdCard(Bitmap bitmap, String filename) {
String stored = null;
File sdcard = Environment.getExternalStorageDirectory();
File folder = new File(sdcard.getAbsoluteFile(), "/imagens");
folder.mkdir();
File file = new File(folder.getAbsoluteFile(), filename);
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
stored = "success";
} catch (Exception e) {
e.printStackTrace();
}
return stored;
}
And I start this process using a button click like this:
mButtonDo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Execute the async task
ArrayList<URL>arrayURL=new ArrayList<URL>();
for (Integer i:arrayID)
{
URL url = stringToURL(getString(R.string.link)+i.toString()+".jpg");
arrayURL.add(url);
}
mMyTask = new DownloadTask().execute(arrayURL);
}
});
And it works as I want too. But the problem now is that I want that this process is automatic and do when the Activity is started, so I putted this code in the OnCreate method:
ArrayList<URL>arrayURL=new ArrayList<URL>();
for (Integer i:arrayID)
{
URL url = stringToURL(getString(R.string.link)+i.toString()+".jpg");
arrayURL.add(url);
}
mMyTask = new DownloadTask().execute(arrayURL);
But it won't do anything, with the button click it starts fine, but in the OnCreate method it wont do anything, do anyone know how to solve this issue? Thanks for your help and time.
EDITED And have this code to fill my arrayID:
public void BuscarIdProduto_Imagens()
{
new Thread(new Runnable() {
public void run() {
String SOAP_ACTION = "http://p4.com/BuscarIdProdutos";
String METHOD_NAME = "BuscarIdProdutos";
//Criar um Pedido SOAP
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//Parametrização do SOAP
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
//O envelope SOAP que se associa ao pedido
envelope.setOutputSoapObject(request);
//Classe: Indicar como o Servidor de WS pode ser alcançado
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try{
//SOAP Request(Pedido)
androidHttpTransport.call(SOAP_ACTION, envelope);
//IR buscar a Resposta que me foi enviado pelo Servidor de WS
SoapObject response = (SoapObject) envelope.bodyIn;
if (response.getPropertyCount() > 0) {
for (int i = 0; i < response.getPropertyCount(); i++) {
SoapPrimitive soapObject = ((SoapPrimitive) response.getProperty(i));
//instanciar o canal de output
arrayID.add(Integer.valueOf(soapObject.toString()));
}
}
System.out.println();
} catch (Exception ex) {
System.out.println("------------------------------>" + ex.toString());
}
}
}).start();
}
I debuged the program and I think the KSOAP finish with his thread after the AsyncTask starts, and that can not be possivel because I need the array filled, is there some way to start the asynctask after the ksoap thread is finish?
Solution
So from your code snippets I assume that problem is calling both methods in onCreate
but both methods do network calls. So basically when you call this part of code:
ArrayList<URL>arrayURL=new ArrayList<URL>();
for (Integer i:arrayID) {
URL url = stringToURL(getString(R.string.link)+i.toString()+".jpg");
arrayURL.add(url);
}
mMyTask = new DownloadTask().execute(arrayURL);
In this case arrayID
didn't get values yet and probably for
loop is skipped and an empty list
or arrayURL
is passed to the AsyncTask
. That will also answer why code works on onClick
because meanwhile arrayID
is populated with data from network.
So what you want is to make sure that arrayID
is populated with data before you call part of code which I pasted above. So create an interface
inside your Activity
for example:
public interface OnDataFetched {
void fetchSuccess(ArrayList<URL> arrayID);
}
Now go to your Activity
and implement
this interface
and override
method fetchSuccess
:
public class YourAcitivity extends AppCompatActivity implements OnDataFetched
...
@Override
public void fetchSuccess(ArrayList<URL> arrayID) {
}
After that in same Activity
create a field:
private OnDataFetched onDataFetched;
Inside onCreate
:
onDataFetched = this;
After that go into your BuscarIdProduto_Imagens
method after for
loop:
if (response.getPropertyCount() > 0) {
for (int i = 0; i < response.getPropertyCount(); i++) {
SoapPrimitive soapObject = ((SoapPrimitive) response.getProperty(i));
//instanciar o canal de output
arrayID.add(Integer.valueOf(soapObject.toString()));
}
if(onDataFetched != null)
onDataFetched.fetchSuccess(arrayID);
}
And the last thing move AsyncTask
code inside ovirrieded fetchSuccess
:
@Override
public void fetchSuccess(ArrayList<URL> arrayID) {
for (Integer i:arrayID) {
URL url = stringToURL(getString(R.string.link)+i.toString()+".jpg");
arrayURL.add(url);
}
mMyTask = new DownloadTask().execute(arrayURL);
}
Answered By - Yupi
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.