我正在"尝试调用虚拟方法' int android.graphics.Bitmap.getWidth()'在空对象引用" (下面的完整堆栈跟踪)。我觉得令人困惑的是,引用的行是类的 final 属性 - 当类的实例存在引用它时,它应该已经定义:
public class WindView extends View {
...
private final Bitmap pDirectionArrow = BitmapFactory.decodeResource(getResources(), R.drawable.wind_arrow);
...
public void setWindOriginDegrees(float mWindOriginDegrees) {
this.mWindOriginDegrees = mWindOriginDegrees;
_rotateArrow();
invalidate();
}
...
private Matrix _rotateArrow() {
pMatrix.setRotate((180+mWindOriginDegrees)%360, pDirectionArrow.getWidth() / 2, pDirectionArrow.getHeight() / 2);
return pMatrix;
}
public class DetailFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
...
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
...
WindView windGraphic = new WindView(getActivity());
windGraphic.setWindSpeed((int) windSpeedStr);
windGraphic.setWindOriginDegrees(windDirStr);
windGraphic.setForegroundColor(getResources().getColor(R.color.sunshine_light_blue));
windGraphic.setBackgroundColor(getResources().getColor(R.color.sunshine_dark_blue));
parent.addView(windGraphic, parent.indexOfChild(mWindView) + 1);
package com.example.android.sunshine.app;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by RobertoTomás on 0023, 23/3/2016.
*/
public class WindView extends View {
private static final float GESTURE_THRESHOLD_DIP = 16.0f;
private final Bitmap pDirectionArrow = BitmapFactory.decodeResource(getResources(), R.drawable.wind_arrow);
private final Bitmap pCompassRing = BitmapFactory.decodeResource(getResources(), R.drawable.wind_compass_ring);
private final Paint pSpeedText = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Matrix pMatrix = new Matrix();
private Float pDensity;
private Rect pSpeedTextBoundingRectangle;
private int mForegroundColor;
private int mBackgroundColor;
private int mWindSpeed;
private float mWindOriginDegrees;
public float getWindOriginDegrees() {
return mWindOriginDegrees;
}
public void setWindOriginDegrees(float mWindOriginDegrees) {
this.mWindOriginDegrees = mWindOriginDegrees;
_rotateArrow();
invalidate();
}
public int getForegroundColor() {
return mForegroundColor;
}
public void setForegroundColor(int foregroundColor) {
this.mForegroundColor = foregroundColor;
_changeForegroundColor();
invalidate();
}
private void _changeForegroundColor(){
int [] allpixels = new int [pDirectionArrow.getHeight()* pDirectionArrow.getWidth()];
pDirectionArrow.getPixels(allpixels, 0, pDirectionArrow.getWidth(), 0, 0, pDirectionArrow.getWidth(), pDirectionArrow.getHeight());
for(int i = 0; i < allpixels.length; i++)
{
if(allpixels[i] == Color.BLACK)
{
allpixels[i] = mForegroundColor;
}
}
pDirectionArrow.setPixels(allpixels, 0, pDirectionArrow.getWidth(), 0, 0, pDirectionArrow.getWidth(), pDirectionArrow.getHeight());
}
public int getBackgroundColor() {
return mBackgroundColor;
}
public void setBackgroundColor(int backgroundColor) {
this.mBackgroundColor = backgroundColor;
_changeBackgroundColor();
invalidate();
}
private void _changeBackgroundColor(){
int [] allpixels = new int [pCompassRing.getHeight()* pCompassRing.getWidth()];
pCompassRing.getPixels(allpixels, 0, pCompassRing.getWidth(), 0, 0, pCompassRing.getWidth(), pCompassRing.getHeight());
for(int i = 0; i < allpixels.length; i++)
{
if(allpixels[i] == Color.BLACK)
{
allpixels[i] = mBackgroundColor;
}
}
pCompassRing.setPixels(allpixels, 0, pCompassRing.getWidth(), 0, 0, pCompassRing.getWidth(), pCompassRing.getHeight());
}
public int getWindSpeed() {
return mWindSpeed;
}
public void setWindSpeed(int wind_speed) {
this.mWindSpeed = wind_speed;
invalidate();
}
public String getWindSpeedText (){
return Integer.toString(mWindSpeed);
}
/** Constructors **/
public WindView(Context c){
super(c);
objectHandler();
}
public WindView(Context c, AttributeSet attrs) {
super(c, attrs);
objectHandler();
}
public WindView(Context c, AttributeSet attrs, int DefaultStyle) {
super(c, attrs, DefaultStyle);
objectHandler();
}
public void objectHandler(){
this.mForegroundColor = getResources().getColor(R.color.primary_dark_material_light);
this.mBackgroundColor = getResources().getColor(R.color.primary_material_dark);
this.mWindSpeed = 0;
this.mWindOriginDegrees = 0;
this.pDensity = getContext().getResources().getDisplayMetrics().density;
this.pSpeedText.setStyle(Paint.Style.FILL);
this.pSpeedText.setColor(mForegroundColor);
this.pSpeedText.setAntiAlias(true);
int textSize = (int) (GESTURE_THRESHOLD_DIP * pDensity + 0.5f);
textSize *= pDensity;
this.pSpeedText.setTextSize(textSize);
this.pSpeedText.setTextAlign(Paint.Align.LEFT);
Typeface typeface = Typeface.create(Typeface.SANS_SERIF,Typeface.BOLD_ITALIC);
this.pSpeedText.setTypeface(typeface);
this.pSpeedTextBoundingRectangle = new Rect();
}
private Matrix _rotateArrow() {
pMatrix.setRotate((180+mWindOriginDegrees)%360, pDirectionArrow.getWidth() / 2, pDirectionArrow.getHeight() / 2);
return pMatrix;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(18 * pDensity, 18 * pDensity);
canvas.drawBitmap(pCompassRing, 0, 0, null);
String txt = pSpeedText + " km/h";
pSpeedText.getTextBounds(
txt, // text
0, // start
txt.length(), // end
pSpeedTextBoundingRectangle // bounds
);
canvas.drawText(
txt, // Text to draw
canvas.getWidth() / 2, // x
canvas.getHeight() / 2 + Math.abs(pSpeedTextBoundingRectangle.height()) / 2, // y
pSpeedText // Paint
);
canvas.drawBitmap(pDirectionArrow, _rotateArrow(), null);
}
}
03-23 18:37:47.870 4152-4152/com.example.android.sunshine.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.sunshine.app, PID: 4152
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
at com.example.android.sunshine.app.WindView._rotateArrow(WindView.java:147)
at com.example.android.sunshine.app.WindView.setWindOriginDegrees(WindView.java:42)
at com.example.android.sunshine.app.DetailFragment.onLoadFinished(DetailFragment.java:227)
at com.example.android.sunshine.app.DetailFragment.onLoadFinished(DetailFragment.java:44)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:427)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:395)
at android.support.v4.content.Loader.deliverResult(Loader.java:104)
at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:73)
at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:35)
at android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:223)
at android.support.v4.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:61)
at android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:461)
at android.support.v4.content.ModernAsyncTask.access$500(ModernAsyncTask.java:47)
at android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:474)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
答案 0 :(得分:0)
将您的位图声明更改为:
private Bitmap pDirectionArrow;
然后在视图的构造函数中调用位图上的get资源,如下所示:
pDirectionArrow = BitmapFactory.decodeResource(c.getResources(), R.drawable.wind_arrow);
getResources需要应用程序的上下文。
答案 1 :(得分:0)
所以事实证明问题在于BitmapFactory.decodeResource(getResources(), R.drawable.wind_arrow);
假定资源将变为BitmapDrawable
而不是VectorDrawable
。在我看来,这很容易成为android中的一个bug。 我要报告。我symfony documentation。
解决方案是在构造函数中分配它,如:
private Bitmap _getBitmap(int drawableId, int color) {
Drawable vectorDrawable;
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.LOLLIPOP){
vectorDrawable = getResources().getDrawable(drawableId,null);
}else {
vectorDrawable = getResources().getDrawable(drawableId);
}
// Wrap the drawable so that future tinting calls work
// on pre-v21 devices. Always use the returned drawable.
Drawable wrapDrawable = DrawableCompat.wrap(vectorDrawable);
DrawableCompat.setTint(wrapDrawable.mutute(), getResources().getColor(color));
int h = vectorDrawable.getIntrinsicHeight();
int w = vectorDrawable.getIntrinsicWidth();
//Setting a pixel default if intrinsic height or width is not found , eg a shape drawable
h=h>0?h:96;
w=w>0?w:96;
wrapDrawable.setBounds(0, 0, w, h);
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bm);
wrapDrawable.draw(canvas);
return bm;
}
现在我实际上仍然遇到颜色问题(mutate
和wrap
都突出显示为红色并且没有使用Alt +输入提供分辨率),但这只是在我检查后用螺栓固定基本解决方案有效。