是否可以启动一个新意图并让它在单独的线程中运行?
我有点卡住了。我的应用程序中有一个活动无法执行,因为它冻结了主 ui 线程。我可以在日志猫中看到,因为它长时间没有响应,所以它只会杀死整个应用程序并关闭......这完全糟糕。
所以......我从菜单启动这个过程,并通过调用意图......基本的东西来启动它。但我正在调用的活动正在查询手机以获取手机内部和外部的所有图像文件。我尝试在内部类中使用 AsyncTask
但它只是超出了我对如何正确执行的理解。我不确定什么会回到哪里以及什么。
因此我的问题是我可以创建一个新线程来在调用意图时启动并让活动在该线程上运行吗?听起来这比我检查我的活动并尝试使 AsyncTask
正常工作更容易。
我想它看起来像这样,也许
Thread t = new Thread(){
public void run(){
//start mark creation dialog view
Intent intentMarkCreation = new Intent(MixView.this, MarkCreation.class);
startActivityForResult(intentMarkCreation, 10);
}
};
t.start();
我知道 android 对于常规线程应该表现得很奇怪,但我不知道如何使用 AsyncTask
并且我能找到的深入例子并不多。 如果有人可以通过一些示例或高级教程为我阐明这一点,我将非常感激。 :)
哦,这是我试图放入 asyncTask 中的一堆损坏的代码
public class GraffMarkCreation extends AsyncTask {
/* ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.planets_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
fileChooser.setAdapter(adapter); */
private EditText nameMark;
private EditText describeMark;
private Spinner fileChooser;
private Button SaveMarkForLaterUpload;
private Button uploadMark;
private RadioGroup radioButtonLayout;
private ProgressBar uploadProgress;
private Gallery fileGalleryChooser;
private ImageButton goBackButton;
@Override
public void onCreate(Bundle savedInstancedState)
{
super.onCreate(savedInstancedState);
this.setContentView(R.layout.markcreationform);
this.describeMark = (describeMark);
findViewById(R.id.describeMark);
this.nameMark = (nameMark);
findViewById(R.id.nameMark);
this.fileChooser = (fileChooser);
findViewById(R.id.fileChooser);
this.SaveMarkForLaterUpload = (SaveMarkForLaterUpload);
findViewById(R.id.SaveMarkForLaterUpload);
this.uploadMark = (uploadMark);
findViewById(R.id.uploadMark);
this.radioButtonLayout = (radioButtonLayout);
findViewById(R.id.radioButtonLayout);
this.uploadProgress = (uploadProgress);
findViewById(R.id.uploadProgress);
this.fileGalleryChooser = (fileGalleryChooser);
findViewById(R.id.fileGalleryChooser);
this.goBackButton = (goBackButton);
findViewById(R.id.goBackButton);
}}
////////////create list of images to populate the spinner view with///////////////////////
/* class findImages extends AsyncTask<String[],String,Cursor>{
@Override
protected Cursor doInBackground(String[]... arg0) {
// TODO Auto-generated method stub
String[] projection = { MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA };
String selection = "";
String[] selectionArgs = null;
Cursor mImageExternalCursor = managedQuery
(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, selection, selectionArgs,null);
Cursor mImageInternalCursor = managedQuery(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
projection, selection, selectionArgs, null);
mImageExternalCursor.getString(mImageExternalCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
mImageInternalCursor.getString(mImageExternalCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
return mImageInternalCursor;
}
}
findImages findThemImages = new findImages();
String[] params = null;
findThemImages.execute(params);
////////////////////////////////////////////////////////////////////////////////////////////
radioButtonLayout.setOnCheckedChangeListener(this); */
/////Hook up radio buttons///////////////////////////////////////////////
/*
@Override
public void onCheckedChanged(RadioGroup radioButtonLayout, int buttonId) {
// TODO Auto-generated method stub
switch (buttonId){
case 1:
///if image button selected spinner is populated with
///list of images to chose from
/* String[] projection = { MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA };
String selection = "";
String[] selectionArgs = null;
Cursor mImageExternalCursor = managedQuery
(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, selection, selectionArgs, null);
Cursor mImageInternalCursor = managedQuery(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
projection, selection, selectionArgs, null);
mImageExternalCursor.getString(mImageExternalCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
mImageInternalCursor.getString(mImageExternalCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
*/
/*
break;
case 2:
///if audio button selected spinner is populated with
///list of audio files to chose from
break;
case 3:
///if video button selected spinner is populated with
///list of videos to chose from
break;
case 4:
///if text button selected spinner is not populated and
///user will be uploading only a basic mark with text only
break;
}
}
Im kinda stuck. I have an activity in my app that just wont go through because its freezing up the main ui thread. I can see in the log cat that because its unresponsive for so long that it just kills the whole app and shuts down....which totally sucks.
so....I launch this process from a menu and I have it started by calling an intent....basic stuff. But the activity I'm calling is querying the phone for all image files inside and outside the phone. Ive tried to use AsyncTask
in an inner class but its just a hair outside my understanding on how to do it properly. I`m not sure whats returning to where and what.
Therefore my question is can I just create a new thread to be launched on the call of the intent and have the activity run on that? It sounds like it would be an easier solution than for me to go through my activity and try making an AsyncTask
work right.
I`m thinking it would look like this maybe
Thread t = new Thread(){
public void run(){
//start mark creation dialog view
Intent intentMarkCreation = new Intent(MixView.this, MarkCreation.class);
startActivityForResult(intentMarkCreation, 10);
}
};
t.start();
I know android is supposed to act weird with regular threads but I cant figure out how to use AsyncTask
and there's not to many good in depth examples I could find.
If some one could shed some light on this for me with either some examples or an advanced tutorial on it I would be super duper greatful. :)
Oh heres the broken bunch of code that I was trying to put into an asyncTask
public class GraffMarkCreation extends AsyncTask {
/* ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.planets_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
fileChooser.setAdapter(adapter); */
private EditText nameMark;
private EditText describeMark;
private Spinner fileChooser;
private Button SaveMarkForLaterUpload;
private Button uploadMark;
private RadioGroup radioButtonLayout;
private ProgressBar uploadProgress;
private Gallery fileGalleryChooser;
private ImageButton goBackButton;
@Override
public void onCreate(Bundle savedInstancedState)
{
super.onCreate(savedInstancedState);
this.setContentView(R.layout.markcreationform);
this.describeMark = (describeMark);
findViewById(R.id.describeMark);
this.nameMark = (nameMark);
findViewById(R.id.nameMark);
this.fileChooser = (fileChooser);
findViewById(R.id.fileChooser);
this.SaveMarkForLaterUpload = (SaveMarkForLaterUpload);
findViewById(R.id.SaveMarkForLaterUpload);
this.uploadMark = (uploadMark);
findViewById(R.id.uploadMark);
this.radioButtonLayout = (radioButtonLayout);
findViewById(R.id.radioButtonLayout);
this.uploadProgress = (uploadProgress);
findViewById(R.id.uploadProgress);
this.fileGalleryChooser = (fileGalleryChooser);
findViewById(R.id.fileGalleryChooser);
this.goBackButton = (goBackButton);
findViewById(R.id.goBackButton);
}}
////////////create list of images to populate the spinner view with///////////////////////
/* class findImages extends AsyncTask<String[],String,Cursor>{
@Override
protected Cursor doInBackground(String[]... arg0) {
// TODO Auto-generated method stub
String[] projection = { MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA };
String selection = "";
String[] selectionArgs = null;
Cursor mImageExternalCursor = managedQuery
(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, selection, selectionArgs,null);
Cursor mImageInternalCursor = managedQuery(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
projection, selection, selectionArgs, null);
mImageExternalCursor.getString(mImageExternalCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
mImageInternalCursor.getString(mImageExternalCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
return mImageInternalCursor;
}
}
findImages findThemImages = new findImages();
String[] params = null;
findThemImages.execute(params);
////////////////////////////////////////////////////////////////////////////////////////////
radioButtonLayout.setOnCheckedChangeListener(this); */
/////Hook up radio buttons///////////////////////////////////////////////
/*
@Override
public void onCheckedChanged(RadioGroup radioButtonLayout, int buttonId) {
// TODO Auto-generated method stub
switch (buttonId){
case 1:
///if image button selected spinner is populated with
///list of images to chose from
/* String[] projection = { MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA };
String selection = "";
String[] selectionArgs = null;
Cursor mImageExternalCursor = managedQuery
(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, selection, selectionArgs, null);
Cursor mImageInternalCursor = managedQuery(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
projection, selection, selectionArgs, null);
mImageExternalCursor.getString(mImageExternalCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
mImageInternalCursor.getString(mImageExternalCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
*/
/*
break;
case 2:
///if audio button selected spinner is populated with
///list of audio files to chose from
break;
case 3:
///if video button selected spinner is populated with
///list of videos to chose from
break;
case 4:
///if text button selected spinner is not populated and
///user will be uploading only a basic mark with text only
break;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
据我了解,
Activity
必须在 UI 线程上运行。最好的选择是使用AsyncTask
或IntentService
。由于您正在收集将在 UI 中使用的资源,因此我建议使用AsyncTask
(阅读 这个)。您是否在
Activity
中创建了一个扩展AsyncTask
的内部类?如果是这样,我会说你已经快到了。这使您的AsyncTask
可以轻松访问Activity
中的View
。也许如果您发布代码,我可以让您知道需要如何重构/修复它。As far as I understand it
Activity
s must be run on the UI thread. Your best options are to use theAsyncTask
or anIntentService
.Since you are gathering resources that you are going to use in the UI, I would recommend theAsyncTask
(read this).Did you create an inner class inside your
Activity
that extendsAsyncTask
? If so I'd say you're almost there. That allows yourAsyncTask
easy access to theView
s in theActivity
. Maybe if you post the code I can let you know how it needs to be refactored/fixed.创建一个扩展 AsyncTask< 的新类(外部公共或内部私有)参数、进度、结果>其中 <> 中的值是对象类型。将长时间运行的代码放入名为
public Result doInBackground(Params... params)
的新方法中。创建 AsyncTask 的新实例,设置您需要的任何值(通过标准 setter 方法)(传递主 UI 的上下文是一个好主意),然后调用
instance.execute()
来运行doInbackground
方法。创建以下方法来显示和隐藏进度条:通读 Gary 链接到的指南并查看我写的内容 - 它应该全部放在一起。
Create a new class (either external public or internal private) that extends AsyncTask< Params, Progress, Result> where those values in <> are object types. Put the long running code within a new method named
public Result doInBackground(Params... params)
.Create a new instance of your AsyncTask, set whatever values you need (via standard setter methods) (passing the main UI's context is a good idea), then call
instance.execute()
as to rundoInbackground
method. Create the following methods to show and hide a progress bar:Read through the guide that Gary linked to and look what I've written - it should all come together.