【问题标题】:How to Correctly Start Activity from custom View (Java Class)?如何从自定义视图(Java 类)正确启动 Activity?
【发布时间】:2013-11-07 08:08:41
【问题描述】:

我正在尝试定义一个自定义 Java 类(扩展 LinearLayout),它需要在点击时启动一个活动。我的代码如下所示:

public ArizaSatiri(Context context/*, AttributeSet attrs , final Activity aktivite*/ , JSONObject mysql_satiri)
    {
        super(context/*, attrs*/);

        // code to initialize my view :

        final Context finalContext = context;

        this.setOnClickListener(new OnClickListener() {@Override
            public void onClick(View v) {
                Intent newIntent = new Intent(finalContext, ArizaDetaylari.class);
                finalContext.startActivity(newIntent);
            }//onClick
        });


    }

但是当我点击实例化视图时,我得到了错误:

Calling startActivity() from outside of an Activity  context requires the  
FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

从代码中可以看出,我尝试将Activity 传递给构造函数,并且成功了。但这是正确的方法吗?你会推荐哪种方式?

编辑:

我还需要在某个时候致电setTypeFace()。我应该使用上下文还是 Activity?

【问题讨论】:

  • 查看为 getContext() 方法。你可以用它代替你的 finalContext

标签: java android android-intent android-activity android-custom-view


【解决方案1】:

试试这个:

this.setOnClickListener(new OnClickListener() {@Override
        public void onClick(View v) {
            Intent newIntent = new Intent(finalContext, ArizaDetaylari.class);
            newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            finalContext.startActivity(newIntent);
        }//onClick
    });

【讨论】:

  • 谢谢! FLAG_ACTIVITY_NEW_TASK 做什么?我害怕丢失共享偏好等数据。有什么害处吗?
  • 不,未删除共享首选项数据。在 Android 文档中,您可以阅读:developer.android.com/reference/android/content/…
  • 这个答案应该被接受。 Android 建议在尝试从 Activity 上下文之外启动新 Activity 时使用此标志 FLAG_ACTIVITY_NEW_TASK
【解决方案2】:

您可以将代码放入自定义视图类的onAttachedToWindow()

@Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                final Context context = ArizaSatiri.this.getContext();
                Intent intent = new Intent(context , ArizaDetaylari.class);
                context.startActivity(intent);
            }
        });
    }

这很有帮助,因为在您的视图添加到活动后调用此函数,视图具有它的引用。视图的构造函数可能在添加到活动之前运行,因此会出现错误。

如果您在 xml 中声明视图而不是以编程方式创建它,这也应该有效。 (尚未测试)

【讨论】:

    【解决方案3】:

    如果查看Context class reference,您会发现 Activity 是一个间接子类。因此,如果您使用 Activity 作为上下文,您的代码应该可以工作。

    例如:

    public ArizaSatiri(Context context, JSONObject mysql_satiri){ ...}
    

    您可以更改对 ArizaSatiri 构造函数的调用:

    new ArizaSatiri(myActivity, mysql_satiri);
    

    希望对你有帮助。

    【讨论】:

    • 这看起来是对的。我试图从上下文转换为活动,但它没有用。现在试试这个。谢谢!
    【解决方案4】:

    如果您使用的上下文 (finalContext) 指的是 ApplicationContext,那么您需要使用该标志。只需在finalContext.startActivity(newIntent);前加上一句newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);即可

    这种方法的问题,尤其是当您在应用程序之外启动某些东西时,例如:邮件客户端等,即使在活动完成后,它是否会继续存在于最近的应用程序堆栈中,如果是邮件客户端,它会继续存在即使在邮件发送后也能在那里

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      • 2013-07-18
      • 1970-01-01
      相关资源
      最近更新 更多