1

我正在编写一个涉及选择多个图像并将它们上传到解析服务器的 Android 应用程序。我已经使用 Telegram Android Gallery 选择器实现了多个图像选择,我现在可以将它们上传到 Parse,但是将它们转换为位图会使应用程序冻结 15 分钟,所以我试图将这部分代码在后台移动到 no有用,我最终保存了一个空数组。我假设任务在保存之前没有结束或者执行不正确。欢迎所有输入!

谢谢!这是代码:

public class AddProductActivity extends AppCompatActivity implements View.OnClickListener {
private Bitmap bitmap;
private byte[] byteArray;
private List<String> photos;
private ArrayList<ParseFile> images;
private ImageButton imageButton;
private Future future;
private ExecutorService executorService;

@Override
public void onClick(View view) {
    if (view.getId() == R.id.addImageBtn) {
        GalleryConfig config = new GalleryConfig.Build()
                .limitPickPhoto(8)
                .singlePhoto(false)
                .hintOfPick("Vous pouvez choisir un max de 8 photos.")
                .filterMimeTypes(new String[]{"image/*"})
                .build();
        GalleryActivity.openActivity(AddProductActivity.this, 2, config);
    }
}

public void publish(View view) {
    EditText productName = (EditText) findViewById(R.id.productNameField);
    EditText productDescription = (EditText) findViewById(R.id.productDescriptionField);
    EditText productPrice = (EditText) findViewById(R.id.priceField);

    if (productName.getText().toString().matches("")
            || productDescription.getText().toString().matches("")
            || productPrice.getText().toString().matches("")) {

        Toast.makeText(this, "Tous les champs sont requis", Toast.LENGTH_SHORT).show();

    } else {

        if (byteArray == null) {

            Toast.makeText(AddProductActivity.this, "Ajoutez des images de l'article!", Toast.LENGTH_SHORT).show();

        } else {

            ParseObject object = new ParseObject("Product");

            object.put("name", productName.getText().toString());
            object.put("description", productDescription.getText().toString());
            object.put("price", productPrice.getText().toString());
            object.put("city", ParseUser.getCurrentUser().get("City").toString());
            object.put("username", ParseUser.getCurrentUser().getUsername());
            object.addAll("productImages", images);

            object.saveInBackground(new SaveCallback() {
                @Override
                public void done(ParseException ex) {
                    if (ex == null) {
                        executorService.shutdown();
                        // Try uploading the ParseFiles using the save method before associating them with the Parse Object
                        Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                        startActivity(intent);
                    } else {
                        Toast.makeText(AddProductActivity.this, "Il y a eu un soucis, réessayer dans 5mins!", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    //async task
    photos = (List<String>) data.getSerializableExtra(GalleryActivity.PHOTOS);

    executorService = Executors.newSingleThreadExecutor();
    future = executorService.submit(new Callable(){
        public Object call() throws Exception {
            images = new ArrayList<ParseFile>();
            for (String photo : photos) {
                bitmap = BitmapFactory.decodeFile(photo);
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
                byteArray = stream.toByteArray();

                ParseFile file = new ParseFile("image.png", byteArray);
                try {
                    file.save();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                images.add(file);
                Log.i("Size", String.valueOf(images.size()));
            }
            return images;
        }
    });

}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_product);

    imageButton = (ImageButton) findViewById(R.id.addImageBtn);
    imageButton.setOnClickListener(this);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayShowTitleEnabled(false);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setDisplayShowHomeEnabled(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 2);
            }
        }
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // handle arrow click here
    if (item.getItemId() == android.R.id.home) {
        finish(); // close this activity and return to preview activity (if there is any)
    }

    return super.onOptionsItemSelected(item);
} }

这是XML文件

<LinearLayout
android:id="@+id/activity_add_product"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.shopapp.AddProductActivity"
android:orientation="vertical"
android:weightSum="1">

<!-- our toolbar -->
<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

<TextView
    android:text="@string/addProductTextview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/addProductTextview"
    android:textAlignment="center"
    android:textSize="24sp"
    android:textStyle="normal|bold"
    android:textColor="?attr/actionModeSplitBackground" />

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="textPersonName"
    android:ems="10"
    android:id="@+id/productNameField"
    android:hint="@string/productNameField" />

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="textMultiLine"
    android:ems="10"
    android:id="@+id/productDescriptionField"
    android:hint="@string/productDrescriptionField" />

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="numberDecimal"
    android:ems="10"
    android:id="@+id/priceField"
    android:hint="@string/productPriceField" />

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@android:drawable/ic_menu_camera"
    android:id="@+id/addImageBtn"
    android:contentDescription="@string/addImageProductBtnDescription" />

<Button
    android:text="@string/publishProductBtn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/publishProductBtn"
    android:onClick="publish" />

4

1 回答 1

1

在@Kishore Jethava 的指导下找到了答案

关键是

executorService.shutdown()当你ArrayList装满所有的时候你应该关机ParseFile

注意:它会上传图片,但仍然需要一些时间 - 大约 3 分钟。接下来我会调查的!

这是该类最后的样子:

public class AddProductActivity extends AppCompatActivity implements View.OnClickListener {
private Bitmap bitmap;
private byte[] byteArray;
private List<String> photos;
private ArrayList<ParseFile> images;
private ImageButton imageButton;
private Future future;
private ExecutorService executorService;
private ParseObject object = new ParseObject("Product");

@Override
public void onClick(View view) {
    if (view.getId() == R.id.addImageBtn) {
        GalleryConfig config = new GalleryConfig.Build()
                .limitPickPhoto(8)
                .singlePhoto(false)
                .hintOfPick("Vous pouvez choisir un max de 8 photos.")
                .filterMimeTypes(new String[]{"image/*"})
                .build();
        GalleryActivity.openActivity(AddProductActivity.this, 2, config);
    }
}

public void publish(View view) {
    EditText productName = (EditText) findViewById(R.id.productNameField);
    EditText productDescription = (EditText) findViewById(R.id.productDescriptionField);
    EditText productPrice = (EditText) findViewById(R.id.priceField);

    if (productName.getText().toString().matches("")
            || productDescription.getText().toString().matches("")
            || productPrice.getText().toString().matches("")) {

        Toast.makeText(this, "Tous les champs sont requis", Toast.LENGTH_SHORT).show();

    } else {

        if (images == null) {

            Toast.makeText(AddProductActivity.this, "Ajoutez des images de l'article!", Toast.LENGTH_SHORT).show();

        } else {

            object.put("name", productName.getText().toString());
            object.put("description", productDescription.getText().toString());
            object.put("price", productPrice.getText().toString());
            object.put("city", ParseUser.getCurrentUser().get("City").toString());
            object.put("username", ParseUser.getCurrentUser().getUsername());

            object.saveInBackground(new SaveCallback() {
                @Override
                public void done(ParseException ex) {
                    if (ex == null) {
                        // Try uploading the ParseFiles using the save method before associating them with the Parse Object
                        Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                        startActivity(intent);
                    } else {
                        Toast.makeText(AddProductActivity.this, "Il y a eu un soucis, réessayer dans 5mins!", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    //async task
    photos = (List<String>) data.getSerializableExtra(GalleryActivity.PHOTOS);

    ExecutorService executorService = Executors.newSingleThreadExecutor();

    executorService.execute(new Runnable() {
        public void run() {
            images = new ArrayList<ParseFile>();
            for (String photo : photos) {
                bitmap = BitmapFactory.decodeFile(photo);
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
                byteArray = stream.toByteArray();

                ParseFile file = new ParseFile("image.png", byteArray);
                try {
                    file.save();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                images.add(file);
            }
            object.addAll("productImages", images);
            object.saveInBackground();
            Log.i("Added?", "YES");
        }
    });

    executorService.shutdown();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_product);

    imageButton = (ImageButton) findViewById(R.id.addImageBtn);
    imageButton.setOnClickListener(this);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayShowTitleEnabled(false);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setDisplayShowHomeEnabled(true);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 2);
        }
    }
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // handle arrow click here
    if (item.getItemId() == android.R.id.home) {
        finish(); // close this activity and return to preview activity (if there is any)
    }

    return super.onOptionsItemSelected(item);
}
}

再次感谢@kishore Jethava

于 2017-01-05T16:12:36.540 回答