3

最近誰かが私のコードにコメントし、私は次のことを宣言しました:

private Bitmap splashBackground;
private Bitmap lightDot;
private static Bitmap scaledBackground;
private static Bitmap scaledLightDot;

彼らは、サティックビットマップを宣言しないように私にアドバイスしました。

しかし、私はすべてを試しましたが、静的であると宣言しない限り、コードは機能しません。

また、「public static Bitmap createScaledBitmap(Bitmap src、int dstWidth、int dstHeight、boolean filter)」が公式のAndroidデベロッパーサイトに表示されているようですので、何をすべきか、何をすべきでないかについて少し混乱しています。

任意のポインタをいただければ幸いです-ありがとう

編集:明確にするために:

宣言から静的を削除すると、onDraw()メソッドに到達するまでに、スケーリングされたビットマップはnullになります。(私はinitialise()メソッドでスケーリングされたビットマップオブジェクトを作成しています。作成されると、それは有効です(つまり、nullではありません)-しかし、静的として宣言しない限り、onDrawでnullになるようです。

アクティビティクラスからinitialise()メソッドを呼び出しています。

編集:要求に応じてより多くのコード。

OnCreateメソッド:ご覧のとおり、画面の高さと幅を渡して、スケーリングされたビットマップを作成できるようにしています。

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        displaySplashScreen= new SplashScreen(this);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        // set View
        setContentView(new SplashScreen(this));
        WindowManager w = getWindowManager();   
        Display d = w.getDefaultDisplay();
        int width=d.getWidth();
        int height=d.getHeight();
        displaySplashScreen.initialise(width, height);
}

私の初期化方法:

 public void initialise(int w, int h)
 {       
     //Get width and height (passed in from Activity)

     vwidth=w;
     vheight=h;

     //Create pre-scaled bitmaps

    scaledBackground = Bitmap.createScaledBitmap(splashBackground,  vwidth, vheight, true);
    scaledLightDot = Bitmap.createScaledBitmap(lightDot, vwidth, vheight, true);

 }

また、同じ方法で標準変数(int number;など)を使用し、それをinitalise(number = 5;)に設定すると、初期化メソッドのnumberは5になります。onDraw()からログに記録すると、常に「0」が繰り返し返されます。それは困惑しています。

これまでの皆さん、ありがとうございました。さらにコードが必要な場合はお知らせください......

4

4 に答える 4

1

一般に、sに利用することstaticBitmap非常に悪い考えです。これには多くの正当な理由がありますが、主にメモリリークの回避に関係しています。

また、「public static Bitmap createScaledBitmap(Bitmap src、int dstWidth、int dstHeight、boolean filter)」が公式のAndroidデベロッパーサイトに表示されているようです...

これはではありませんstatic Bitmap。これは、クラスメソッドへのメソッド呼び出しです。静的は同じようには機能せず、戻りタイプ(Bitmap)は静的ではありません。これが意味するのは、メソッドが静的であり、インスタンスを呼び出す必要がないということです。選択した適切な変数に配置されるビットマップが返されます。

initialise()アクティビティクラスからメソッドを呼び出しています。

この声明はまったく役に立たない。クラスのどこから呼ばれていますか?、、、、他のカスタムメソッドにありますかonCreate()?特定のことをどこでいつ行うかを選択すると、それらがどれほど成功するかについて大きな影響を与える可能性があります。onStart()onResume()

...しかし、静的として宣言しない限り、onDrawでnullになるようです。

これにはいくつかの理由が考えられますが、コードがないため、実際には適切な回答がありません。ここにいくつかの注意点があります。

  • これは、アクティビティが再作成されていることが原因である可能性があります。
  • これは、無関係と思われるメソッドが実際に呼び出されていることが原因である可能性もあります。これはおそらく、手動でに設定している場所ですnull
  • createScaledBitmap()これは、メソッドの不適切な使用が原因である可能性があります。
  • メモリが少ないためにビットマップがリサイクルされている可能性があります(これは実際には思ったよりも頻繁に発生します)

編集:コードを確認した後

これが原因のようです。上に、あなたは...

displaySplashScreen= new SplashScreen(this);

以下に追加します...

setContentView(new SplashScreen(this));

これは、2つのスプラッシュスクリーンを作成していることを意味します。使用していないときにnullポインタを取得する理由の1つは、使用staticしている行のさらに下にあるためかもしれません...

displaySplashScreen.initialise(width, height);

ただし、contentViewは新しいSplashScreenに設定されているため、実際にはそのビューを利用していません。これを解決するには、同じビューオブジェクトと通信していることを確認してください。IE

setContentView(displaySplashScreen);

これにより、少なくとも同じオブジェクトを見ていることが確認されます。他に何が起こっているかによっては、少し再編成しなければならない可能性があります。例えば、

setContentView(displaySplashScreen);

...以下に表示する必要がある場合があります...

 displaySplashScreen.initialise(width, height);

これはあなたがおもちゃにしなければならないかもしれないものですが、他にすぐにわかるものは他にありません。nullpointerexceptionsを解決すると、最初はコードでより多くのエラーが明らかになることがよくあることに注意してください。コースにとどまり、それぞれを順番に解決します。

于 2013-02-12T02:39:45.857 に答える
1

この行は間違っています:

    // set View
    setContentView(new SplashScreen(this));        // This line is wrong.

これである必要があります:

    // set View
    setContentView(displaySplashScreen);        // displaySplashScreen is created earlier.

の2つのインスタンスが作成されますSplashScreen。同じインスタンスを使い続ける必要があります。

于 2013-02-12T03:55:44.500 に答える
0

いや、これは静的変数です

private Bitmap splashBackground;
private Bitmap lightDot;
private static Bitmap scaledBackground;
private static Bitmap scaledLightDot;

これは静的メソッドです

public static Bitmap createScaledBitmap (Bitmap src, 
     int dstWidth, int dstHeight, boolean filter)

静的変数は通常、定数に対して宣言され、クラスがある場合、変数は例としてオブジェクトではなくクラスに属します

public class car {
      private static colorOfCar;
      private numberOfDoor;
}

クラスの車があり、車のクラスからオブジェクトporscheとferrariを作成するときに、2つの変数colorOfCarとnumberOfDoorがあるとします。ドアの数を変更すると、ポルシェオブジェクトとフェラーリオブジェクトのnumberOfDoorは異なりますが、 colorOfCarを変更するcolorOfCarはオブジェクトではなくクラスに属する静的オブジェクトであるため、ポルシェオブジェクトとフェラーリオブジェクトの両方のcolorOfCarが変更されます。

私の説明をご理解いただければ幸いです。私の答えがあなたを助けているのを見つけたら、投票して私の答えを受け入れてください。他に質問がある場合は、コメントで気軽に質問してください、ありがとうございます:)

于 2013-02-12T01:10:25.033 に答える
0

コードがないと、ビューが複数回作成されていることを使用しているようです。ビューの2つのインスタンスであるか、同じビューが再作成されている可能性があります(アクティビティの再開)。初めて、initialize()がonDraw()の前に呼び出され、静的Drawableが初期化されて有効になります。2回目は、initialize()の前にonDraw()が実行されます(これは、Drawableが静的な場合に機能します)。これは、ビューを膨らませ、後でinitialize()を呼び出したことが原因である可能性があります(これは、ビューがすでにレイアウトに含まれていることを意味します)。すなわち

public void onCreate(Bundle savedInstanceState) {
  setContentView(R.layout.mylayout); //the view is added to layout, onDraw() may be called
  MyView view = (MyView)findViewById(R.id.myview);
  view.initialize();  //initializing the drawable from null
  //no guarentee that initialize was called before onDraw()
}

Drawableが静的な場合、これは正常に実行されます。これは、2番目のビューが描画されるときに、最初のビューによって初期化されたものと同じDrawableを使用しているためです。スタティックを削除するときは、onDraw()の前に常にinitializeが呼び出されるようにする必要があります。

アクティビティからinitialize()を呼び出す代わりに、ビューのコンストラクターから呼び出してみませんか?私はよく次のパターンを使用します。

public class MyView extends View {

  private Bitmap splashBackground;
  private Bitmap lightDot;
  private Bitmap scaledBackground;
  private Bitmap scaledLightDot;

  public MyView(Context context) {
    super(context);
    init();
  }

  public MyView(AttributeSet attr, Context context) {
    super(attr, context);
    //parse attr for xml attributes
    init();
  }

  private void init() {
    splashBackground = getResources().getDrawable(R.drawable.splash_background);
    lightDot = getResources().getDrawable(R.drawable.light_dot);
    scaledLightDot = Bitmap.createScaledBitmap(lightDot, getDPI(32), getDPI(32), false);
  }

  public void onSizeChanged(int width, int height) {
    scaledBackground =  Bitmap.createScaledBitmap (splashBackground, width, height, false);
  }

  /**
   * Convert pixel value to device independent pixels (DPI)
   * @params pixels  Value for pixel size for MDPI screens
   */
  private int getDPI(int pixels) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, pixels, getResources().getDisplayMetrics());
  }

  public void onDraw(Canvas canvas) {
    //non-static drawables are guaranteed to be not-null
    canvas.draw(scaledBackground, 0, 0, null);
    canvas.draw(scaledLightDot, 10, 10, null);
  }
}

あなたはすべて設定されます

于 2013-02-12T03:22:17.407 に答える