是否可以启动一个新意图并让它在单独的线程中运行?

发布于 2024-11-15 14:27:29 字数 5326 浏览 1 评论 0原文

我有点卡住了。我的应用程序中有一个活动无法执行,因为它冻结了主 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烦人精 2024-11-22 14:27:29

据我了解,Activity必须在 UI 线程上运行。最好的选择是使用 AsyncTaskIntentService。由于您正在收集将在 UI 中使用的资源,因此我建议使用 AsyncTask (阅读 这个)。

您是否在 Activity 中创建了一个扩展 AsyncTask 的内部类?如果是这样,我会说你已经快到了。这使您的 AsyncTask 可以轻松访问 Activity 中的 View。也许如果您发布代码,我可以让您知道需要如何重构/修复它。

As far as I understand it Activitys must be run on the UI thread. Your best options are to use the AsyncTask or an IntentService.Since you are gathering resources that you are going to use in the UI, I would recommend the AsyncTask (read this).

Did you create an inner class inside your Activity that extends AsyncTask? If so I'd say you're almost there. That allows your AsyncTask easy access to the Views in the Activity. Maybe if you post the code I can let you know how it needs to be refactored/fixed.

囍孤女 2024-11-22 14:27:29

创建一个扩展 AsyncTask< 的新类(外部公共或内部私有)参数、进度、结果>其中 <> 中的值是对象类型。将长时间运行的代码放入名为 public Result doInBackground(Params... params) 的新方法中。

创建 AsyncTask 的新实例,设置您需要的任何值(通过标准 setter 方法)(传递主 UI 的上下文是一个好主意),然后调用 instance.execute() 来运行 doInbackground 方法。创建以下方法来显示和隐藏进度条:

ProgressDialog pdia;
protected void onPreExecute()
{
    super.onPreExecute();
    pdia = new ProgressDialog(context);
    pdia.setMessage("Loading...");
    pdia.show();

}

protected void onPostExecute(Result result)
{
    super.onPostExecute(result);
    if (context != null){
    pdia.dismiss();    
}

通读 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 run doInbackground method. Create the following methods to show and hide a progress bar:

ProgressDialog pdia;
protected void onPreExecute()
{
    super.onPreExecute();
    pdia = new ProgressDialog(context);
    pdia.setMessage("Loading...");
    pdia.show();

}

protected void onPostExecute(Result result)
{
    super.onPostExecute(result);
    if (context != null){
    pdia.dismiss();    
}

Read through the guide that Gary linked to and look what I've written - it should all come together.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文