【问题标题】:Send view as a parameter in Asynctask在 Asynctask 中将视图作为参数发送
【发布时间】:2012-10-21 00:17:03
【问题描述】:

我正在处理我正在膨胀视图的代码,当用户单击一个视图时,我需要执行解析 URL,然后检查解析是否返回我。问题是我需要在 asynctask 解析中进行才能不出现异常,并且在任务结束之前进行检查。

理想的做法是将视图作为参数发送到 AsyncTask 以将我的所有代码发送到 Asynctask。但不是如何做到这一点

我放代码是为了更容易理解。

vMens.setOnClickListener(new View.OnClickListener() {

    public void onClick(View vMens) {
        int readOK=0;
        try{
            new taskMensaje(vMens).execute();

            if(mess_gest.equals("1")){
                readOK=1;
            }else{
                readOK=0;
            }
        }catch(Exception e){
            Utils.showDialog(Calendario.this, "Error", "No se puede gestionar el mensaje");
        }
            if (readOK==0){
                Mess.state = message.get(vMens.getId()).p1;
                Mess.tittle = message.get(vMens.getId()).p2;
            else{
                //message no gest
            }
    }
});
private class taskMensaje extends AsyncTask<String, Void, View> {

    @Override
    protected String doInBackground(String... params) {
        MensajeriaGestionablePARSER parserMensGest = new MensajeriaGestionablePARSER(urlMensGest);
        gestionables = parserMensGest.parse();

        mess_gest = gestionables.get(0).p0;
        return "";
    }
}

有解决这个问题的办法吗?

感谢和抱歉我的英语不好

【问题讨论】:

  • 只是小费。首先使用字面量比较字符串是一个好习惯,例如"1".equals(mess_gest)。它有助于避免 NullPointers。您还可以使用TextUtils.equals("1", mess_gest) 比较字符串。 TextUtils 由 android SDK 提供。

标签: android view android-asynctask parameter-passing


【解决方案1】:

您可以将其作为参数传递给构造函数并将其存储在 AsyncTask 对象中。 将其存储为 WeakReference 并在 onPostExecute 上检查它,就像显示来自官方文档 http://developer.android.com/training/displaying-bitmaps/process-bitmap.html 的图像的最佳实践一样

private class TaskMensaje extends AsyncTask<String, Void, Void> {
   private WeakReference vRef;
   ... / your other stuff here   

   public TaskMensaje (View v) {
       vRef = new WeakReference(v);
   }


    @Override
    protected String doInBackground(String... params) {
        MensajeriaGestionablePARSER parserMensGest = new MensajeriaGestionablePARSER(urlMensGest);
        gestionables = parserMensGest.parse();

        mess_gest = gestionables.get(0).p0;
        return null;
    }

    @Override
    protected onPostExecute(Void result) {
        if (vRef != null && bitmap != null) {
           final ImageView imageView = vRef.get();
           if (imageView != null) {
               // Do whatever you want with your ImageView
               ...
           }
       }
    }
}

顺便说一句,请参阅 AsyncTask 参考文档以了解如何在类定义中使用通用参数;-) 在http://developer.android.com/reference/android/os/AsyncTask.html

【讨论】:

  • 我必须投射 vRef: final ImageView imageView = (ImageView)vRef.get();
【解决方案2】:

如果您想将View 作为参数发送给AsyncTask,简短的回答是不要

视图来来去去,很有可能在你的AsyncTask 完成时,你的View 已经死去,除了悲伤和沮丧之外,试图访问它不会给你任何东西.

异步处理数据的正确模式是创建一个单独的数据处理类,即Observable,包括所有AsyncTasks,花里胡哨。并使您的View 类成为Observer,它注册接收更新并等待数据处理完毕并通过update() 回调提供给它。

请记住,AsyncTask 是故意从 UI 中分离数据处理,尝试将其绑定回来是完全不合逻辑的。

【讨论】:

    【解决方案3】:

    您可以在异步任务中创建一个构造函数,通过它您可以传递视图并在需要时在异步任务中使用它。

    喜欢下面

    private class taskMensaje extends AsyncTask<String, Void, String> {
    
        private View _view 
        public taskMensaje(View view){
            this._view = view; // this you can use ahead wherever required
        }
    
        @Override
        protected String doInBackground(String... params) {
            MensajeriaGestionablePARSER parserMensGest = new MensajeriaGestionablePARSER(urlMensGest);
            gestionables = parserMensGest.parse();
    
            mess_gest = gestionables.get(0).p0;
            return "";
        }
    }
    

    【讨论】:

    • 感谢您的回复,怎么办?如何发送我的视图 vMens?
    • 你已经在做 :) new taskMensaje(vMens).execute();
    • 为什么 View 在你的 asynctask 中使用了第三个参数?
    • 第三个参数是doInBackground方法传递给onPostExecute方法的参数
    • 你的意思是你返回的字符串是一个视图?
    【解决方案4】:

    试试这个

     vMens.setOnClickListener(new View.OnClickListener() {
    
            public void onClick(View vMens) {
                int readOK=0;
                try{
                    new taskMensaje().execute(vMens);
    
                    if(mess_gest.equals("1")){
                        readOK=1;
                    }else{
                        readOK=0;
                    }
                }catch(Exception e){
                    Utils.showDialog(Calendario.this, "Error", "No se puede gestionar el mensaje");
                }
                    if (readOK==0){
                        Mess.state = message.get(vMens.getId()).p1;
                        Mess.tittle = message.get(vMens.getId()).p2;
                    else{
                        //message no gest
                    }
            }
        });
    
    private class taskMensaje extends AsyncTask<View, Void, String> {
    
    
    
         @Override
            protected String doInBackground(View... params) {
               //Do what ever you want to do with this view
        View v=params[0];
                return "";
            }
        }
    

    【讨论】:

    • 这几乎是对的,你应该调用“new taskMensaje().execute(vMens);”
    • 这是非常危险的。 Android View 对象不是线程安全的,在doInBackground() 中对它们进行任何操作都可能导致间歇性和难以调试的崩溃。如果您需要在解析完成后更新View,请覆盖onPostExecute() method并将您的View相关代码放入其中。
    • @acj 我知道这不是使用视图的好方法。我刚刚告诉“rgrocha”正在传递的 AsynTask 中的参数序列
    猜你喜欢
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    相关资源
    最近更新 更多