【问题标题】:StartActivity from different context来自不同上下文的 StartActivity
【发布时间】:2013-09-23 19:47:31
【问题描述】:

我有一个主类和一个单独的类 (OnClickBtn.java),我只想在其中保留按钮方法。 我想不是从主类而是从 OnClickBtn.java 开始新的活动。

我已运行该程序,但它在启动时崩溃。我想我的主要问题与 Intent 对象“Intent int_btnOpenA =new Intent(objContex, ActivityA.class)”的代码有关

这是我的代码,MainActivity.java:

 package com.example.and2dtest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
//START***VIEW LIST E BOTTONI
    TextView txtView01;
    Button btnOpenA;
    Button btnOpenB;
    EditText editText1;

    OnClickBtn btnMethods=new OnClickBtn(this);
//END***VIEW LIST E BOTTONI

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//Start***set buttons views
        txtView01=(TextView)findViewById(R.id.txtView01);
        btnOpenA=(Button)findViewById(R.id.btnOpenA);
        btnOpenB=(Button)findViewById(R.id.btnOpenB);
        editText1=(EditText)findViewById(R.id.editText1);   

        btnOpenA.setOnClickListener(btnMethods);
        btnOpenB.setOnClickListener(btnMethods);
//end***set buttons views
    }




    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }



}

这是 OnClickBtn.java 类:

package com.example.and2dtest;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;

public class OnClickBtn extends Activity implements OnClickListener {
MainActivity objContex;

    public OnClickBtn(MainActivity cont){
    objContex=cont;
    }

    Intent int_btnOpenA =new Intent(objContex, ActivityA.class); //<<THIS CAUSES CRASH!

    @Override
    public void onClick(View v) {
        switch(v.getId()){
        case R.id.btnOpenA:
            Log.d("ZR", "in case btnOpenA");
            //this.startActivity(int_btnOpenA);  //<-clearly This Wont Start
            break;
        case R.id.btnOpenB:
            Log.d("ZR","in case btnOpenB");
            //do something
            break;

        }   
    }


}

我怎样才能让它工作,保持 startActivity 方法不在主要活动中?

谢谢,路德

好的,我一直在弄乱代码,以下似乎有效,ActivityA 不是从 MainActivity.java 而是从 OnClickBtn.java 开始的,正如我试图做的那样。 这是代码:

MainActivity.java:

package com.example.and2dtest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
//START***VIEW LIST E BOTTONI
    TextView txtView01;
    Button btnOpenA;
    Button btnOpenB;
    EditText editText1;


//END***VIEW LIST E BOTTONI

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        OnClickBtn btnMethods=new OnClickBtn(this);
//Start***set buttons views
        txtView01=(TextView)findViewById(R.id.txtView01);
        btnOpenA=(Button)findViewById(R.id.btnOpenA);
        btnOpenB=(Button)findViewById(R.id.btnOpenB);
        editText1=(EditText)findViewById(R.id.editText1);   

        btnOpenA.setOnClickListener(btnMethods);
        btnOpenB.setOnClickListener(btnMethods);
//end***set buttons views
    }




    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }



}

OnClickBtn.java:

package com.example.and2dtest;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;

public class OnClickBtn implements OnClickListener {
Context objContext;

    public OnClickBtn(Context con){
    //v=view;
    objContext=con;
    }

    //Intent int_btnOpenA =new Intent(objContext, ActivityA.class);

    @Override
    public void onClick(View v) {
        switch(v.getId()){
        case R.id.btnOpenA:
            Log.d("ZR", "in case btnOpenA");
            Intent int_btnOpenA =new Intent(objContext, ActivityA.class);
            objContext.startActivity(int_btnOpenA);
            break;
        case R.id.btnOpenB:
            Log.d("ZR","in case btnOpenB");
            //do something
            break;

        }   
    }


}

ActivityA.java:

package com.example.and2dtest;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class ActivityA extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activity);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity, menu);
        return true;
    }

}

【问题讨论】:

  • 这是什么原因?你想重复使用它们还是只想让你的另一个Activity“更干净”?
  • 只是保持清洁,但最重要的是,在这一点上理解为什么这是不可能的
  • 看我的回答。希望它会为您清除它。

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


【解决方案1】:

正如其他人所说,以这种方式实例化Activity 是不好的,并且不起作用。他们没有用户定义的构造函数。它们只能用Intent 实例化。

您可以在点击类中使用implements OnClickListener。你在那里override 并把你的代码放在那里。

Here is an answer that demonstrates that.

如果您希望它们可重复使用并且在每个 Activity 中具有相同的功能,那么您可以将它们放在 BaseActivity 中,您将在另一个 extend 中放置 Activities

这个解释多一点in this SO answer

【讨论】:

    【解决方案2】:

    尝试在 onCreate() 方法中设置 btnMethods,而不是在类级别。

    .....
    
    OnClickBtn btnMethods;
    
    .....
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        btnMethods = new OnClickBtn(this);
        ......
    }
    

    【讨论】:

    • 将所有 btnMethods 放在 onCreate 中会起作用,我知道,但我想知道是否有办法让它们像我的代码一样工作。
    • 通常的方法是在 MainActivity 中为 OnClickListener 创建匿名类,或者使 MainActivity 也成为 OnClickListener,实现 onClick 方法,而不是创建特定的类作为 onClickListener。这样它就不那么复杂了,你也不会遇到像这样的问题。
    【解决方案3】:

    您不能自己实例化活动。虽然 OnClickBtn 扩展了一个 Activity,但它并没有作为一个 Activity 运行。

    【讨论】:

    • 这不是程序崩溃的原因,我已经排除了 Activity 扩展,仍然无法正常工作
    • 因为它不尊重活动生命周期,当你这样做时: Intent int_btnOpenA =new Intent(objContex, ActivityA.class);它当然会崩溃..因为 OnClickBtn 的构造函数在调用 MainActivity 的 onCreate() 方法之前被调用,因此您传递给这个 Intent 的上下文还不存在......它当然是一个存在的 Java 对象,但不是 Android 环境中存在的 Context 对象。
    • 所以,虽然不是很漂亮,但是如果把新的 OnClickBtn() 调用移到 MainActivity 的 onCreate() 方法中,就不会再崩溃了。
    【解决方案4】:

    给 MainActiviy 一个以 Context 作为参数的构造函数。保存该上下文(或将其用于 getActivityContext() 以在您收到按钮单击时使用。

    这是 Android 中的常用技术。您会看到许多对象将 Context 作为其构造函数的参数。

    此外,正如 Alécio 在回答中所说,MainActivity 不应扩展 Activity。任何将其用作活动的尝试都可能失败。

    【讨论】:

      【解决方案5】:

      试试这个:

      Intent int_btnOpenA;
      public OnClickBtn(MainActivity cont){
       int_btnOpenA=new Intent(cont, ActivityA.class);
      }
      

      【讨论】:

        【解决方案6】:

        试试这样:

        (只需更改“btnOpenA.setOnClickListener(btnMethods);”和“btnOpenB.setOnClickListener(btnMethods);”这两个,忘记按钮类)


            btnOpenA.setOnClickListener(new OnClickListener() {
        
                @Override
                public void onClick(final View view) {
                    final Intent intent = new Intent(MainActivity.this, ActivityA.class);
                    SensorActivity.this.startActivity(intent);
                }
            });
        
        
            btnOpenB.setOnClickListener(new OnClickListener() {
        
                @Override
                public void onClick(final View view) {
                    final Intent intent = new Intent(MainActivity.this, ActivityB.class);
                    SensorActivity.this.startActivity(intent);
                }
            });
        

        编辑:如果你非常想要那个按钮类,你可以试试这个:

        (在你的活动中使用这个“监听器类”嵌套类注册监听器,或者将它更改为公共并将其放在不同的文件中,然后使用这个“监听器类”注册监听器。上下文仍然与主活动。)

        private final class OnClickBtn implements OnClickListener {
            @Override
            public void onClick(final View view) {
        
                if( view.getId() == R.id.btnOpenA ){
        
                    final Context context = view.getContext();
                    final Intent intent = new Intent(context, ActivityA.class);
                    view.getContext().startActivity(intent);
                }
                else if( view.getId() == R.id.btnOpenB ){
        
                    final Context context = view.getContext();
                    final Intent intent = new Intent(context, ActivityB.class);
                    view.getContext().startActivity(intent);
                }
            }
        }
        

        【讨论】:

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