【问题标题】:Android Custom View: getting null references on every class members in the onDraw methodAndroid自定义视图:在onDraw方法中获取每个类成员的空引用
【发布时间】:2015-03-15 21:01:03
【问题描述】:

我正在尝试创建一个 android 自定义视图,但遇到了一个相当奇怪的问题。

我在构造函数中设置的每个数据成员(String、Bitmap、...)在覆盖的 onDraw 方法中都变为 null。

代码如下:

public class SimulationView extends View
{
private static final String TAG = "SIMULATION_VIEW";
private String str;
private Bitmap mField;

public SimulationView(Context context) {
    super(context);
    str = new String("hello"); 
    mField = BitmapFactory.decodeResource(getResources(), R.drawable.field);
    Log.i(TAG_DEBUG, mField.getHeight() + " " + mField.getWidth()); // displays "1518 900" properly
    Log.i(TAG, str); // displays "hello" properly
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Log.i(TAG, str); // throws java.lang.NullPointerException
    Log.i(TAG, mField.getHeight() + " " + mField.getWidth()); // throws java.lang.NullPointerException (when previous line is commented of course)
    invalidate();
}

public SimulationView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

public SimulationView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context);
}

private void init(Context context) {
}

这是 String 导致 NPE 时的堆栈跟踪:

   Process: com.example.simulation_view, PID: 5207
java.lang.NullPointerException: println needs a message
        at android.util.Log.println_native(Native Method)
        at android.util.Log.i(Log.java:160)
        at com.example.simulation_view.SimulationView.onDraw(SimulationView.java:84)
        at android.view.View.draw(View.java:15114)

这是 位图 导致 NPE 时的堆栈跟踪:

  java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getHeight()' on a null object reference
        at com.example.simulation_view.SimulationView.onDraw(SimulationView.java:83)
        at android.view.View.draw(View.java:15114)

我做错了什么? 任何帮助将不胜感激!

祝你有美好的一天

【问题讨论】:

  • 如何通过构造函数在 Context 或 xml 中在代码上创建 SimulationView?还是一次在 xml 上,一次在代码中?

标签: java android nullpointerexception android-view ondraw


【解决方案1】:

您的 init 方法为空。仅当您以编程方式实例化自定义视图时,您的代码才有效。如果在 xml 中声明,则不会初始化 Bitmap 和 String。使用init进行初始化,并在仅以Context为参数的构造函数中调用它

private void init(Context context) {
    str = "hello"; 
    mField = BitmapFactory.decodeResource(getResources(), R.drawable.field);
}

【讨论】:

  • 嗯,这似乎解决了问题!非常感谢@Blackbelt!但我很好奇,为什么没有应用构造函数中的实例化?
  • 当您在 xml 中声明自定义视图时,调用的构造函数是带有两个参数的构造函数,SimulationView(Context context, AttributeSet attrs),在这个构造函数中,您没有初始化您在 onDraw 中使用的对象
  • 好的,但是在我的应用程序设计中,我通过调用一个参数构造函数来实例化我的自定义视图。 (在 MainActivity 中):mSimulationView = new SimulationView(this)
  • 您声明您在一个布局中查看了吗?
  • 是的,我为此自定义视图创建了一个 xml 布局文件。
【解决方案2】:
mField = BitmapFactory.decodeResource(getResources(), R.drawable.field);

此行返回一个空对象,因此当您尝试访问getHeight() 方法时,它将引发空指针异常。尝试验证参数是否符合您的预期。

对于onDraw() 方法,您应该考虑全局变量String str 的范围。在您的 onDraw() 方法中,当它到达 Log.i(TAG, str); 时,它很可能没有被赋值。考虑改用局部变量并将其作为参数传递给必要的方法。

【讨论】:

  • 就像我在构造函数中评论的那样,Log函数正确显示了位图的高度和宽度,因此证明decodeResource没有返回空对象。
  • 看Blackbelt的回答,我相信他说问题出在你的init函数是正确的。
  • 是的,这确实解决了问题!不过感谢您的帮助!我真的很想知道为什么在我的构造函数中进行的实例化在运行时没有应用于其余代码......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 2015-04-10
  • 2011-10-02
  • 2016-09-10
  • 2012-03-03
相关资源
最近更新 更多