繁体   English   中英

如何将上下文传递给 android 库中的 Intent?

[英]How to pass context to Intent in android library?

我在 android 中为循环屏幕创建了一个库,当我尝试在我的活动中实现它时,我收到了这个错误消息。

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.app.Activity.getApplicationContext()' on a null object reference
        at com.expert.recur.ScreenReco.<init>(ScreenReco.java:15)
        at com.expert.recurringscreen.MainActivity.onCreate(MainActivity.java:18)

我的代码。 MainActivity.java:

public class MainActivity extends AppCompatActivity {

    ScreenReco screenReco;

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

        screenReco=new ScreenReco(MainActivity.this);//line 18
        screenReco.value = 1000;
        screenReco.runnable.run();

    }
}

我的图书馆:

public class ScreenReco {
    Activity activity;

    public ScreenReco(Activity activity) {
        this.activity = activity;
    }

    public Context context = activity.getApplicationContext();//line 15
    public int value;
    public Handler handler = new Handler();
    public Runnable runnable = new Runnable() {
        @Override
        public void run() {
            Intent i = new Intent(context, context.getClass());
            handler.postDelayed((Runnable) context,value);
            context.startActivity(i);
        }
    };
}
 java.lang.NullPointerException: Attempt to invoke virtual method
 'android.content.Context android.app.Activity.getApplicationContext()'
 on a null object reference

您可以创建一个Constructor

构造函数是一种特殊方法,每当使用 new 关键字创建 object 时都会调用该方法。

public class ScreenReco {
Activity activity;     

     ScreenReco(Activity ctx)
     {
       this.activity=ctx
     }

}

然后

ScreenReco screenReco=new ScreenReco(MainActivity.this);

或者

      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      screenReco=new ScreenReco(MainActivity.this);

在将值分配给其变量之前,您应该创建ScreenReco class 的 object ...

public class MainActivity extends AppCompatActivity {

ScreenReco screenReco;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      screenReco=new ScreenReco(); // you are missing this
      screenReco.context = this;
      screenReco.value = 1000;
      screenReco.runnable.run();
  }

}

但我强烈建议您为此使用构造函数......这是一个好习惯

您的MainActivity几乎没问题。 但是,不建议调用run(); Runnable object 我们自己的方法。 相反,在Thread object 的构造函数中传递Runnable object 并调用start(); Thread object 上的方法并让系统调用run(); 在适当的时候使用方法本身。 您改进后的MainActivity可能如下所示:

public class MainActivity extends AppCompatActivity {

    ScreenReco screenReco;

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

        screenReco=new ScreenReco(MainActivity.this, 1000);//line 18
        // screenReco.value = 1000;
        // if you want to run `runnable` in a new Thread
        // new Thread(screenReco.runnable).start();

        //or if you want to run it in the same thread
        //new Handler().post(screenReco.runnable);

        //screenReco.runnable.run();

    }
}  

现在进入您的库文件,即ScreenReco.java ,当您尝试在 class 中调用getApplicationContext()方法时,看起来activity变量尚未初始化,正如@PraveenSP 的回答已经说过的那样。 更好的做法是一次声明所有必需的 class 变量,然后在 class 构造函数中将它们全部初始化为:

public class ScreenReco {
    // if you need this activity variable to just use as context
    // then do not use this variable here just use context only
    Activity activity;
    // the better practice here is to declare these variable as private 
    // and pass values for these variables in constructor and initialize them there 
    public Context context;
    public int value;
    public Handler handler;
    public Runnable runnable;

    // constructor improved from your code
    public ScreenReco(Activity activity, int value) {
        this.activity = activity;// this only if you are using activity
        // object to something otherwise get rid of this variable.
        this.context = activity.getApplicationContext();
        this.handler = new Handler();
        this.value = value;
        this.runnable = new Runnable() {
        @Override
        public void run() {
            Intent i = new Intent(context, context.getClass());
            // handler.postDelayed((Runnable)context, value); 
            context.startActivity(i);
        }
        // this is the edit you need 
        this.handler.postDelayed(runnable, value);
    };
    }

   // this version of constructor is what exactly I would have done by declaring class variable as `private` up there 
   // public ScreenReco(Context context, int value) {
        // this.activity = activity;
        // this.context = context;
        // this.handler = new Handler();
        // also initialize `value` and `runnable` object here
        // this.value = value;
        // this.runnable = new Runnable() {
        // @Override
        // public void run() {
            // Intent i = new Intent(context, context.getClass());
            // handler.postDelayed((Runnable) context,value);
            // context.startActivity(i);
        // }
    // };
    // }
}  

此外,我对您在runnablerun()方法中编写的代码感到非常困惑 看起来您正试图从MainActivity MainActivity 而且,在下面的行中,您尝试将context变量强制转换为Runnable ,这很容易出错。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM