Android 循环以逐个上载列表图像
我想一个接一个地上传多个图像,就像用户点击upload all按钮一样,它必须从列表中可见的第一个图像开始,一旦第一个图像上传到服务器,则必须自动启动第二个图像进行上传,但间隔一秒或两秒后,列表中的所有可用图像也是如此 这是我的代码,允许我上传单个图像:- 上传单个图像的代码Android 循环以逐个上载列表图像,android,android-listview,Android,Android Listview,我想一个接一个地上传多个图像,就像用户点击upload all按钮一样,它必须从列表中可见的第一个图像开始,一旦第一个图像上传到服务器,则必须自动启动第二个图像进行上传,但间隔一秒或两秒后,列表中的所有可用图像也是如此 这是我的代码,允许我上传单个图像:- 上传单个图像的代码 // btnUpload holder.uploadImageButton.setOnClickListener(new View.OnClickListener() { public void o
// btnUpload
holder.uploadImageButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Upload
startUpload(position);
}
});
我正在使用下面的代码,但是它同时上传/同步所有图像,我的意思是一起上传,就像我在一个列表中有500张图片,所以它将所有500张图片一起上传,因此当互联网连接中断时,我会出错,很多时候无法获得上传图片的准确状态
private SparseBooleanArray flags = new SparseBooleanArray();
// At onClick, set all the flags to indicate that some data needs to be synced
ImageButton buttonUploadAll = (ImageButton) findViewById(R.id.sync_btn);
buttonUploadAll.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
for(int position=0; position<listView.getAdapter().getCount(); position++)
{
flags.put(position, true);
}
// Calling this would ensure a call to getView() on every
// visible child of the listview. That is where we will check if
// the data is to be synced and displayed or not
((BaseAdapter) listView.getAdapter()).notifyDataSetChanged();
}
});
@Override
// In getView of the listview's adapter
public View getView(int position, View convertView, ViewGroup parent) {
// If this item is to be synced
if(flags.get(position)) {
startUpload();
// Mark as synced
flags.put(position, false);
}
// Rest of the method that draws the view....
}
private SparseBooleanArray flags=new SparseBooleanArray();
//在onClick中,设置所有标志以指示某些数据需要同步
ImageButton ButtonPloadall=(ImageButton)findViewById(R.id.sync_btn);
buttonUploadAll.setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图arg0){
对于(int position=0;position我只需将AsyncTask
s排队,直到不再上传图片
if (++position < flags.size()) {
new UploadFileAsync().execute(String.valueOf(position));
}
if(++position
您可以在AsyncTask的onPostExecute()
或您的statusWhenFinished()
方法中执行此操作。我不确定您是否需要Runnable
HTH
- 写完字节后不要忘记关闭连接
conn.close()
- 您不需要使用任何
可运行程序
/线程
1) 将以下接口添加到异步任务中
:
public interface onImageUploadListener{
void onImageUploaded(String status);
}
2) 在AsyncTask
(我称之为listener)中将其实例声明为类字段,并添加以下构造函数:
public UploadFileAsync(onImageUploadListener listener){
this.listener = listener;
}
3) 如果您使用的是API>11,请使用AsyncTask.THREAD\u POOL\u EXECUTOR
,以防止上载任务阻止您可能正在运行的其他任务
4) 让您的适配器
类(看在上帝的份上,先删除可运行
部分)实现接口:
public class ImageAdapter extends BaseAdapter implements UploadFileAsync.onImageUploadListener
您需要实现onImageUploaded(字符串状态)
方法:
@Override
public void onImageUploaded(String status){
//here you are getting your server response)
//I use a bit of pseudo-code to describe this condition
if(position < lastPosition){
new UploadFileAsync(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, String.valueOf(nextPosition));
}else{
//we are done
}}
listener.onImageUploaded(yourResponseCode);
6) 要强制1秒延迟,只需在doInBackground()方法中调用Thread.sleep(1000);
,就在return语句之前
每次AsyncTask
完成时,都会触发onimageupload()
回调,您可以从此方法反复执行回调,直到完成上载。您也可以向此方法添加更多检查,例如检查错误代码,但这取决于您
希望这能有所帮助。干杯首先创建一个类,如发布在此处的ImageSyncService
。当我从正在进行的项目中提取该类时,该类的许多组件都丢失了,但您将获得概述。如果有什么不清楚的,您可以问我
public class ImageSyncService extends IntentService {
private static final String TAG = "ImageSyncService";
private Image image;
private ImageOpenHelper imageOpenHelper;
private SharedPreferences preferences;
public ImageSyncService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
Logger.d(TAG, "onHandleIntent");
imageOpenHelper = new ImageOpenHelper(getApplicationContext());
preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
image = (Image) intent.getSerializableExtra(Config.REQUEST_EXTRA_OBJECT);
if(image == null)
return;
if(image.getResourceURI() == null) {
image.setSyncStatus(SyncStatus.SYNCING);
imageOpenHelper.updateImage(image, false);
Response response = MultiPartDataServer.postData(Config.URL_IMAGE_UPLOAD, nameValuePairs, null);
/* on success:
*
* image.setSyncStatus(SyncStatus.SYNCED);
* imageOpenHelper.updateImage(image, false);
*
* */
}
}
在uploadAll
按钮上,单击执行以下操作:
ArrayList<Image> images = imageOpenHelper.getUnsyncedImages(SyncStatus.TO_BE_UPLOADED);
Intent imageSyncService = null;
for(Image i: images) {
imageSyncService = new Intent(getApplicationContext(), ImageSyncService.class);
imageSyncService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
imageSyncService.putExtra(Config.REQUEST_EXTRA_OBJECT, i);
startService(imageSyncService);
}
arraylistimages=imageOpenHelper.getUnsyncedImages(SyncStatus.TO_被上传);
Intent imageSyncService=null;
用于(图像i:图像){
imageSyncService=new Intent(getApplicationContext(),imageSyncService.class);
imageSyncService.setFlags(意图、标志、活动、新任务);
imageSyncService.putExtra(Config.REQUEST\u EXTRA\u对象,i);
startService(imageSyncService);
}
希望这有帮助:)==将触发图像上载的活动类====
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
public class MActivity extends Activity implements OnClickListener, ImageStatusUpdater{
String img_url[] = new String[3];
@Override
public void onImageUpload(boolean status, String img_url) {
//here you will get the status update with corresponding
//image url or say image name what ever
}
@Override
public void onClick(View v) {
img_url[0] = "img1_url";
img_url[1] = "img2_url";
img_url[2] = "img3_url";
new ImageUploader(this).execute(img_url);
}
}
import android.os.AsyncTask;
public class ImageUploader extends AsyncTask<String, String, Void>{
ImageStatusUpdater isu;
public ImageUploader(ImageStatusUpdater isu) {
this.isu = isu;
}
@Override
protected Void doInBackground(String... params) {
for (String img_name: params){
//Here you have to write your uploading code
String[] result;
result = new String[1];
result[0] = img_name;
result[1] = "true";
onProgressUpdate(result);
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
this.isu.onImageUpload(Boolean.getBoolean(values[1]), values[0]);
}
}
==从AsyncTask类上传后,接口类将用于更新每个图像的标志===
public interface ImageStatusUpdater {
public void onImageUpload(boolean status, String img_url);
}
==AsyncTask类,实际上传将从该类完成===
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
public class MActivity extends Activity implements OnClickListener, ImageStatusUpdater{
String img_url[] = new String[3];
@Override
public void onImageUpload(boolean status, String img_url) {
//here you will get the status update with corresponding
//image url or say image name what ever
}
@Override
public void onClick(View v) {
img_url[0] = "img1_url";
img_url[1] = "img2_url";
img_url[2] = "img3_url";
new ImageUploader(this).execute(img_url);
}
}
import android.os.AsyncTask;
public class ImageUploader extends AsyncTask<String, String, Void>{
ImageStatusUpdater isu;
public ImageUploader(ImageStatusUpdater isu) {
this.isu = isu;
}
@Override
protected Void doInBackground(String... params) {
for (String img_name: params){
//Here you have to write your uploading code
String[] result;
result = new String[1];
result[0] = img_name;
result[1] = "true";
onProgressUpdate(result);
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
this.isu.onImageUpload(Boolean.getBoolean(values[1]), values[0]);
}
}
导入android.os.AsyncTask;
公共类ImageUploader扩展异步任务{
图像状态更新程序;
公共ImageUploader(ImageStatusUpdater isu){
this.isu=isu;
}
@凌驾
受保护的Void doInBackground(字符串…参数){
for(字符串img_名称:params){
//在这里你必须写你的上传代码
字符串[]结果;
结果=新字符串[1];
结果[0]=img_名称;
结果[1]=“真”;
更新(结果);
}
返回null;
}
@凌驾
受保护的void onProgressUpdate(字符串…值){
super.onProgressUpdate(值);
this.isu.onImageUpload(Boolean.getBoolean(值[1]),值[0]);
}
}
这只是一种演示代码,用于解释流程,您需要在适当的地方编写实际代码。一个一个上传的更简单方法是,只需添加同步(mLock){
在doinBackground
函数中阻塞。该函数使部分代码相互排斥,一次只上载一个图像。这是一个快速修复或解决方法,我不喜欢这种方法实现此目标
// Async Upload
private static final Object mLock = new Object();//have an object to lock, and define out side the async task class
public class UploadFileAsync extends AsyncTask<String, Void, Void> {
String resServer;
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
synchronized(mLock){ //sync block starts
position = Integer.parseInt(params[0]);
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
int resCode = 0;
String resMessage = "";
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
// File Path
String strSDPath = ImageList.get(position).toString();
// Upload to PHP Script
String strUrlServer = "";
try {
/** Check file on SD Card ***/
File file = new File(strSDPath);
if(!file.exists())
{
resServer = "{\"StatusID\":\"0\",\"Error\":\"Please check path on SD Card\"}";
return null;
}
FileInputStream fileInputStream = new FileInputStream(new File(strSDPath));
URL url = new URL(strUrlServer);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
DataOutputStream outputStream = new DataOutputStream(conn
.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream
.writeBytes("Content-Disposition: form-data; name=\"filUpload\";filename=\""
+ strSDPath + "\"" + lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Response Code and Message
resCode = conn.getResponseCode();
if(resCode == HttpURLConnection.HTTP_OK)
{
InputStream is = conn.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int read = 0;
while ((read = is.read()) != -1) {
bos.write(read);
}
byte[] result = bos.toByteArray();
bos.close();
resMessage = new String(result);
}
Log.d("resCode=",Integer.toString(resCode));
Log.d("resMessage=",resMessage.toString());
fileInputStream.close();
outputStream.flush();
outputStream.close();
resServer = resMessage.toString();
} catch (Exception ex) {
ex.printStackTrace();
}
}//Sync block ends
return null;
}
protected void onPostExecute(Void unused) {
statusWhenFinish(position,resServer);
}
}
//异步上传
private static final Object mLock=new Object();//有一个要锁定的对象,并在异步任务类之外定义
公共类UploadFileAsync扩展AsyncTask{
字符串服务器;
受保护的void onPreExecute(){
super.onPreExecute();
}
@凌驾
受保护的Void doInBackground(字符串…参数){
//TODO自动生成的方法存根
已同步(mLock){//同步块启动
position=Integer.parseInt(参数[0]);
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.service.MainActivity" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:onClick="buttonClick"
android:text="Button" />
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/button1"
android:layout_centerHorizontal="true" >
</ListView>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.service"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
>
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService" />
</application>
</manifest>
<?php
$file_path = "uploads/";
$file_path = $file_path . basename( $_FILES['uploaded_file']['name']);
if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path)) {
echo "success";
} else{
echo "fail";
}
?>
public class MyActivity extends Activity{
public static final int LOAD_IMAGE = 1;
public static final MAX_IMAGE_INDEX = 500;
public static final DELAY_TIME = 1*1000; // 1 second
private WorkerThread mWorkerThread;
onCreate(Bundle bundle){
mWorkerThread = new WorkerThread();
mWorkerThread.start();
}
public void onCLick(View pView){
Message message = Message.obtain();
message.what = LOAD_IMAGE;
message.arg1 = 0; // Start from Image index zero;
mWorkerThread.queJob(message, 0);
}
private class WorkerThread{
Looper looper;
Handler handler;
private void init(){
if(!isAlive()){
start();
}
}
public void queJob(Message msg, int delay){
init();
if(handler!=null){
handler.sendMessageDelayed(msg, delay);
}
}
public void run(){
Looper.prepare();
looper = Looper.MyLoop();
handler = new Handler(){
public void handleMessage(Message msg){
if(msg.what==LOAD_IMAGE){
if(msg.agr1<0||msg.arg1>=MAX_IMAGE_INDEX)
return;
inr imageIndex = msg.arg1;
// Create connection here and load image
Message message = Message.obtain();
message.what = LOAD_IMAGE;
if(loadingSuccess){ // Load next image
message.agr1 = msg.arg1 + 1; // increase index to next
}else{ // en que the same failed job
message.arg1 = msg.arg1;
}
queJob(message, DELAY_TIME);
}
}
};
Looper.loop();
}
}
}
BitmapFactory.Options options = new BitmapFactory.Options();
// down sizing image as it throws OutOfMemory Exception for larger
// images
options.inSampleSize = 8;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
imgView.setImageBitmap(bitmap);