使用Android支持注释
我有一个活动,我打开一个图像选取器,当我获得所选的使用Android支持注释,android,multithreading,android-support-library,Android,Multithreading,Android Support Library,我有一个活动,我打开一个图像选取器,当我获得所选的Uri时,我在缓存目录中创建一个文件副本,然后将图像的位置传递给毕加索以加载图像。我这样做是因为一些像谷歌照片这样的应用出于安全原因不允许将实际的URI传递给不同的活动 以下是我的代码: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVi
Uri
时,我在缓存目录中创建一个文件副本,然后将图像的位置传递给毕加索以加载图像。我这样做是因为一些像谷歌照片这样的应用出于安全原因不允许将实际的URI传递给不同的活动
以下是我的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_external_photo_share);
ButterKnife.bind(this);
LogUtil.i(TAG, "onCreate called");
tinyDB = new TinyDB(this);
if (tinyDB.getBoolean(AppConstants.LOGIN_STATE, false)) {
imageUri = (Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM);
if (imageUri == null || imageUri.toString().isEmpty()) {
ExternalPhotoShareActivity.this.finish();
}
String newActualPath = getActualPathFromUri(imageUri);
Uri newUri = null;
if (newActualPath != null) {
newUri = Uri.fromFile(new File(newActualPath));
}
Intent intent = new Intent(ExternalPhotoShareActivity.this, AddCaptionActivity.class);
intent.putExtra("externalImageUri", newUri);
intent.putExtra("externalImagePath", newActualPath);
startActivity(intent);
ExternalPhotoShareActivity.this.finish();
} else {
final Dialog dialog = new Dialog(ExternalPhotoShareActivity.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_external_share_error);
dialog.setCanceledOnTouchOutside(false);
dialog.show();
TextView goBack = (TextView) dialog.findViewById(R.id.textView86);
goBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
if(dialog != null) {
if(dialog.isShowing()) {
dialog.dismiss();
}
}
} catch (final IllegalArgumentException e) {
// Handle or log or ignore
} catch (final Exception e) {
// Handle or log or ignore
}
ExternalPhotoShareActivity.this.finish();
}
});
}
}
private String getActualPathFromUri(Uri selectedImageUri) {
Bitmap bitmap = null;
try {
bitmap = getBitmapFromUri(selectedImageUri);
} catch (IOException e) {
e.printStackTrace();
}
if (bitmap == null) {
return null;
}
File imageFileFolder = new File(getCacheDir(), "galleri5");
if (!imageFileFolder.exists()) {
imageFileFolder.mkdir();
}
FileOutputStream out = null;
File imageFileName = new File(imageFileFolder, "galleri5-" + System.currentTimeMillis() + ".jpg");
try {
out = new FileOutputStream(imageFileName);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (IOException e) {
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return imageFileName.getAbsolutePath();
}
private Bitmap getBitmapFromUri(Uri uri) throws IOException {
ParcelFileDescriptor parcelFileDescriptor =
getContentResolver().openFileDescriptor(uri, "r");
assert parcelFileDescriptor != null;
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
return image;
}
我在活动的onCreate()
方法中调用getActualPathFromUri()
。有时,当gallery中的图像较大时,需要几秒钟才能将图像加载到屏幕上。因此,我考虑在后台线程中执行这两个方法,以便在后台工作完成时显示UI
我最近开始使用并尝试使用@WorkerThread
注释getActualPathFromUri()
。但在我的onCreate()
方法中,它将其标记为红色,并表示应该从工作线程调用此方法,当前推断的线程是main
这样做的正确方式是什么?我是否应该在后台线程中执行它?谢谢。注释
@WorkerThread
或@UIThread
仅用于标记方法。当从与注释约束不匹配的线程调用方法时,Android Studio将引发错误。看
有关使用
异步任务执行线程的建议,请参见。注释@WorkerThread
或@UIThread
仅用于标记方法。当从与注释约束不匹配的线程调用方法时,Android Studio将引发错误。看
有关使用AsyncTask
执行线程的建议,请参见。在本例中,使用注释@WorkerThrad
表示只能从工作线程调用getActualPathFromUri()
。当您从UI线程内部运行的onCreate()
调用它时,lint检测到问题并将其标记
这样注释方法并不意味着在工作线程中运行该方法。在本例中,注释只是一种标记开发人员(如果在团队中工作,则可能与您不同)特定方法将在特定线程中调用的方式
如果您想在实际的工作线程中实际运行该方法,只需在AsyncTask#doInBackground
方法中调用它即可
编辑:如果你不想使用AsyncTask
,你可以使用任何其他Android线程机制,比如IntentService
,gcmtasksservice
等等,但是,你不应该在UI线程内运行它,因为它可能会导致jank。在这种情况下,使用注释@WorkerThrad
可以说getActualPathFromUri()
只能从工作线程调用。当您从UI线程内部运行的onCreate()
调用它时,lint检测到问题并将其标记
这样注释方法并不意味着在工作线程中运行该方法。在本例中,注释只是一种标记开发人员(如果在团队中工作,则可能与您不同)特定方法将在特定线程中调用的方式
如果您想在实际的工作线程中实际运行该方法,只需在AsyncTask#doInBackground
方法中调用它即可
编辑:如果你不想使用AsyncTask
,你可以使用任何其他Android线程机制,比如IntentService
,gcmtasksservice
等等,但是,你不应该在UI线程内运行它,因为它可能会导致jank。@jonas.koeritz我添加了onCreate()方法。请看一看。@jonas.koeritz我添加了onCreate()方法。请看一看。那很好,但我该怎么办?我该怎么做呢?我不想使用AsyncTask。@阿米蒂瓦里您必须使用AsyncTask。为什么要省略它?我不太喜欢语法。恐怕AsyncTask
是最简单的方法。除了AsyncTask,还有其他方法吗?可能是Rx Java?这很好,但我该怎么办?我该怎么做呢?我不想使用AsyncTask。@阿米蒂瓦里您必须使用AsyncTask。为什么要省略它?我不太喜欢语法。恐怕AsyncTask
是最简单的方法。除了AsyncTask,还有其他方法吗?可能在Rx Java?感谢您的澄清。我想注释它可以让我跳过这项任务。谢谢你的澄清。我想注释它可以让我跳过这项任务。