【问题标题】:Is there a way to call `overridePendingTransition` from a class that does not extend the Activity class?有没有办法从不扩展 Activity 类的类中调用“overridePendingTransition”?
【发布时间】:2014-03-12 14:07:11
【问题描述】:

我正在使用另一个类在显示主要活动时在后台运行一些东西,并将该活动的上下文传递给这个后台类。我正在从这个背景类开始另一个活动,但我无法在此处调用overridePendingTransition,因为“方法 overridePendingTransition(int, int) 未定义为 BackgroundClass 类型。”

public class GetUPC extends AsyncTask<Void, Void, Void> 
{       
    @Override
    protected void onPreExecute() 
    {
        ...
    }
    @Override
    protected Void doInBackground(Void... arg0) 
    {
        ...


                    boolean dairy;
                    if(theDairy.equals("N"))
                    {
                        //milk test
                        dairy=true;
                    }
                    else
                    {
                        dairy=false;
                    }



                    //depending on if there is a warning it will either display the warning screen or skip it
                    if(dairy)
                    {
                        Intent intent_warn = new Intent(context, WarningScreen.class);

                        intent_warn.putExtra("Name", str_name);
                        intent_warn.putExtra("Size", str_size);
                        intent_warn.putExtra("Price", str_price);
                        intent_warn.putExtra("Carbs", str_carbs);
                        intent_warn.putExtra("Protein", str_protein);
                        intent_warn.putExtra("Fiber", str_fiber);
                        intent_warn.putExtra("Sugar", str_sugar);
                        intent_warn.putExtra("SatFat", str_satFat);
                        intent_warn.putExtra("TotFat", str_totFat);
                        intent_warn.putExtra("Cholesterol", str_cholesterol);
                        intent_warn.putExtra("Sodium", str_sodium);
                        intent_warn.putExtra("Potassium", str_potassium);
                        intent_warn.putExtra("Calories", str_calories);
                        intent_warn.putExtra("Warning", "Contains Dairy");
                        intent_warn.putExtra("WarningRed", true);
                        Log.e("Warning",intent_warn.getExtras().getString("Warning"));

                        context.startActivity(intent_warn);
                        overridePendingTransition(R.layout.fade_in, R.layout.fade_out);  //THIS PART ISN'T WORKING//
                    }
                    else
                    {
                        Intent intent_menu = new Intent(context, DisplayScreen.class);
                        intent_menu.putExtra("Name", str_name);
                        intent_menu.putExtra("Size", str_size);
                        intent_menu.putExtra("Price", str_price);
                        intent_menu.putExtra("Carbs", str_carbs);
                        intent_menu.putExtra("Protein", str_protein);
                        intent_menu.putExtra("Fiber", str_fiber);
                        intent_menu.putExtra("Sugar", str_sugar);
                        intent_menu.putExtra("SatFat", str_satFat);
                        intent_menu.putExtra("TotFat", str_totFat);
                        intent_menu.putExtra("Cholesterol", str_cholesterol);
                        intent_menu.putExtra("Sodium", str_sodium);
                        intent_menu.putExtra("Potassium", str_potassium);
                        intent_menu.putExtra("Calories", str_calories);
                        intent_menu.putExtra("Warning",  "Contains no allergens");
                        intent_menu.putExtra("WarningRed", false);
                        Log.e("Warning",intent_menu.getExtras().getString("Warning"));

                        context.startActivity(intent_menu);
                    }


                    Log.e("KYLE_DATA_UPCH",str_name+" "+str_price+""+str_size);
                } 
            }
                catch (JSONException e) 
                {
                    e.printStackTrace();
                }

            } 
            else 
            {
                Log.e("ServiceHandler", "Couldn't get any data from the url");
                _errorCode=3;
            }

            return null;
        }
    @Override
    protected void onPostExecute(Void result) 
    {
        ...
    }



}

【问题讨论】:

    标签: android android-intent android-activity transition android-context


    【解决方案1】:

    所以我实际上能够通过在上下文中调用 overridePendingTransition 来解决问题,并将其转换为 Activity。

    ((Activity) context).overridePendingTransition(R.layout.fade_in, R.layout.fade_out);
    

    我意识到这不是最佳做法,并且可能会因更复杂的应用程序而变得混乱,但就我们现在的目的而言,我认为这没问题。我想最终调查@bariscan Kayaoglu 的解决方案,因为它看起来更强大。

    【讨论】:

    • 小心,如果上下文不是活动,这将崩溃。先检查上下文是否是活动。
    【解决方案2】:

    只是为了给 Tims 答案添加一些安全性,在转换之前检查上下文是否是 Activity 的实例:

    if (context instanceof Activity) {
      ((Activity) context).overridePendingTransition(R.layout.fade_in, R.layout.fade_out);
    }
    

    这只是确保您调用的方法确实存在。您也可以使用 try/catch,但我认为这就足够了

    【讨论】:

    • 为什么我们不能 context.overridePendingTransition,因为上下文是活动的? @比约恩
    【解决方案3】:

    最好创建一个接口并回调它的方法。

    myInterface mInterface;
    public interface myInterface {
        public abstract void myTask();
    }
    
    public GetUPC(myInterface mInterface) {
        this.mInterface = mInterface;
    }
    

    在你的 doInBackground 方法中,当你完成后,调用

    mInterface.myTask();
    

    当您创建异步任务时,不要忘记实现您的 Activity 接口并将其发送给您的构造函数。

    myAsyncTask = new GetUPC(this);
    

    您的开发平台会通知您实现未实现的方法,例如 myTask()。您可以在该方法中做任何您想做的事情,同时您可以访问您的活动。

    【讨论】:

    • myTask() 究竟会在这里做什么?界面是否作为另一个活动?那么我需要将意图传递给界面吗?
    • 你可以调用你的 overridePendingTransition(R.layout.fade_in, R.layout.fade_out);在您的 myTask() 中,因为它是一个抽象方法,您将在您的活动中填写它,您的 this 将是您的活动。但是正如我之前所说,要么将上下文转换为活动,要么使用接口触发在异步任务中结束任务的时间,结果将是相同的,您可能会触发 myTask() 方法或 (Activity) 上下文当您的活动为空时。正如我之前所说,异步任务是一个后台线程,它无法知道你在哪个活动中。
    • 更安全的方法是设置一个静态的Activity对象,每次打开一个新的intent时设置它。假设我们创建了一个名为 Statics 的类,并声明了一个静态 Activity,公共静态 Activity 活动;每次创建新意图时,在 onCreate 中将其设置为 Statics.activity = this;这样,您可以确保您的活动活动对象永远不会为空。但是如果你有内存问题,保持静态活动很可能会导致内存泄漏。
    【解决方案4】:

    我认为这不是一个好主意。由于您的课程是异步任务,因此您选择的活动可能不是活动活动,因为您的异步任务将在后台运行。但是,如果您考虑到内存泄漏和空指针,您可以将您的活动发送给您的构造函数。

    【讨论】:

    • 当你说我会选择的活动时,你的意思是我将从这个异步任务开始的活动吗?因为两个活动中的一个活动无论如何都会启动,除非返回错误。为什么这是一个坏主意?
    • 好吧,假设您在屏幕上启动了一个意图 Activity1。从您的 Activity1 开始一个异步任务并将您的 Activity1 发送到您的异步任务构造函数。然后,当您的异步任务正在处理对象 Activity1 时,您启动另一个意图 Activity2。如果您在异步任务中使用 Activity1 对象,您将获得空指针异常,具体取决于内存,或者您所做的更改将不会被看到,因为您的活动活动是 Activity2。这就是 Async 任务的重点,它是异步工​​作的。
    【解决方案5】:

    您不能从后台线程执行任何 UI 更新部分,但如果想要这样做,请覆盖 AsyncTask 类的 onProgressUpdate 并在其中过去您的活动启动代码。调用此方法调用 publishProgress 。在开始活动之前,您必须取消 AsyncTask 否则您的应用程序将会崩溃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-12
      • 1970-01-01
      相关资源
      最近更新 更多