简体   繁体   English

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

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

I created a library for the recurrent screen in android and when I tried to implement it in my activity I got this error message.我在 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)

My code.我的代码。 MainActivity.java: 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();

    }
}

My library:我的图书馆:

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

You can create a Constructor .您可以创建一个Constructor

A constructor is a special method that is called whenever an object is created using the new keyword.构造函数是一种特殊方法,每当使用 new 关键字创建 object 时都会调用该方法。

public class ScreenReco {
Activity activity;     

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

}

Then然后

ScreenReco screenReco=new ScreenReco(MainActivity.this);

Or或者

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

You are supposed to create an object of ScreenReco class before assigning values to its variables...在将值分配给其变量之前,您应该创建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();
  }

}

But I strongly recommend you to use constructors for this... it's the good practice但我强烈建议您为此使用构造函数......这是一个好习惯

Your MainActivity is almost fine.您的MainActivity几乎没问题。 But, it is not recommended to call run();但是,不建议调用run(); method of Runnable object ourself. Runnable object 我们自己的方法。 Instead, pass the Runnable object in a constructor of a Thread object and call start();相反,在Thread object 的构造函数中传递Runnable object 并调用start(); method on the Thread object and let the system call the run(); Thread object 上的方法并让系统调用run(); method itself when it is appropriate.在适当的时候使用方法本身。 Your improved MainActivity may look like this:您改进后的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();

    }
}  

Now moving into your library file ie ScreenReco.java , it looks like activity variable hasn't been initialized while you are trying to call getApplicationContext() method in the class as @PraveenSP's answer has already said.现在进入您的库文件,即ScreenReco.java ,当您尝试在 class 中调用getApplicationContext()方法时,看起来activity变量尚未初始化,正如@PraveenSP 的回答已经说过的那样。 A better practice would be declare all required class variable at once and then initialize them all in the class constructor as:更好的做法是一次声明所有必需的 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);
        // }
    // };
    // }
}  

Also, I'm so confused by the code you wrote inside the runnable 's run() method.此外,我对您在runnablerun()方法中编写的代码感到非常困惑 It looks like you are trying to start the MainActivity from MainActivity .看起来您正试图从MainActivity MainActivity And, in the line below, you tried to cast context variable to Runnable which is very error-prone.而且,在下面的行中,您尝试将context变量强制转换为Runnable ,这很容易出错。

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

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