AsyncTask 未在 oncreate 中执行
AsyncTask not executiong in oncreate
我正在做一个项目,我想从一个文件夹中下载图片,我有这个代码:
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;
}
然后我使用如下按钮单击开始此过程:
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);
}
});
它也能如我所愿。但现在的问题是,我希望这个过程是自动的,并在 Activity 启动时执行,所以我将这段代码放在 OnCreate 方法中:
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);
但它不会做任何事情,点击按钮它开始正常,但在 OnCreate 方法中它不会做任何事情,有人知道如何解决这个问题吗?
感谢您的帮助和时间。
已编辑
并使用此代码填充我的 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();
}
我调试了程序,我认为 KSOAP 在 AsyncTask 启动后完成了他的线程,这不可能是可能的,因为我需要填充数组,有没有什么方法可以在 ksoap 线程完成后启动异步任务?
因此,根据您的代码片段,我认为问题是在 onCreate
中调用了两种方法,但两种方法都进行了网络调用。所以基本上当你调用这部分代码时:
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);
在这种情况下 arrayID
还没有得到值,可能 for
循环被跳过,一个空的 list
或 arrayURL
被传递给 AsyncTask
.这也将回答为什么代码在 onClick
上工作,因为同时 arrayID
填充了来自网络的数据。
所以你想要的是在你调用我上面粘贴的部分代码之前确保 arrayID
填充了数据。因此,在 Activity
中创建一个 interface
例如:
public interface OnDataFetched {
void fetchSuccess(ArrayList<URL> arrayID);
}
现在转到您的 Activity
和 implement
这个 interface
和 override
方法 fetchSuccess
:
public class YourAcitivity extends AppCompatActivity implements OnDataFetched
...
@Override
public void fetchSuccess(ArrayList<URL> arrayID) {
}
之后在同一个 Activity
创建一个字段:
private OnDataFetched onDataFetched;
里面 onCreate
:
onDataFetched = this;
然后在 for
循环之后进入你的 BuscarIdProduto_Imagens
方法:
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);
}
最后一件事移动 AsyncTask
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);
}
我正在做一个项目,我想从一个文件夹中下载图片,我有这个代码:
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;
}
然后我使用如下按钮单击开始此过程:
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);
}
});
它也能如我所愿。但现在的问题是,我希望这个过程是自动的,并在 Activity 启动时执行,所以我将这段代码放在 OnCreate 方法中:
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);
但它不会做任何事情,点击按钮它开始正常,但在 OnCreate 方法中它不会做任何事情,有人知道如何解决这个问题吗? 感谢您的帮助和时间。
已编辑 并使用此代码填充我的 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();
}
我调试了程序,我认为 KSOAP 在 AsyncTask 启动后完成了他的线程,这不可能是可能的,因为我需要填充数组,有没有什么方法可以在 ksoap 线程完成后启动异步任务?
因此,根据您的代码片段,我认为问题是在 onCreate
中调用了两种方法,但两种方法都进行了网络调用。所以基本上当你调用这部分代码时:
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);
在这种情况下 arrayID
还没有得到值,可能 for
循环被跳过,一个空的 list
或 arrayURL
被传递给 AsyncTask
.这也将回答为什么代码在 onClick
上工作,因为同时 arrayID
填充了来自网络的数据。
所以你想要的是在你调用我上面粘贴的部分代码之前确保 arrayID
填充了数据。因此,在 Activity
中创建一个 interface
例如:
public interface OnDataFetched {
void fetchSuccess(ArrayList<URL> arrayID);
}
现在转到您的 Activity
和 implement
这个 interface
和 override
方法 fetchSuccess
:
public class YourAcitivity extends AppCompatActivity implements OnDataFetched
...
@Override
public void fetchSuccess(ArrayList<URL> arrayID) {
}
之后在同一个 Activity
创建一个字段:
private OnDataFetched onDataFetched;
里面 onCreate
:
onDataFetched = this;
然后在 for
循环之后进入你的 BuscarIdProduto_Imagens
方法:
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);
}
最后一件事移动 AsyncTask
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);
}