Thursday, December 19, 2013

Похоже нашел у Андроида серьезную системную ошибку. Может быть конечно я что то сам напортачил, но похоже что как только я объявляю WallpaperService - программу "живого" фона (ну там когда обои живые), операционка начинает этот процесс форкать бесконтрольно с пугающей скоростью. При этом именно клонируется кусок памяти - никакие конструкторы и инициализаторы не отрабатываются и статические переменные реплицируются так же - так что никакой синхронизации организовать не получается, но все при этом отрисовывается на одном и том же окне.

Заметил я это поставив один из параметров отрисовки в зависимости от времени, иначе у процессов форкнутых все идентично и заметить что одну и ту же картинку отрисовывает на самом деле сотни или тысячи процессов невозможно.

Заодно подивился мощности современной техники - система как сумашедшая запускает неимоверное количество процессов одновременно, но этой малюсенькому карманному компбютерку все ни по чем!

Вот программка, которая демонстрирует ошибку - весь экран заполняется постоянно перерисующимися картинками, то есть каждвя картинка перерисовавается, если бы не было бесконтрольной репликвции перерисовывалась бы только одна картинка:
----------------------------------------------------------------------
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.livecubes">

<uses-sdk android:minSdkVersion="7"/>

<uses-feature android:name="android.software.live_wallpaper"/>

<application android:label="@string/wallpapers" android:icon="@drawable/ic_launcher_wallpaper">

<service android:label="@string/wallpaper_cube1" android:name=".cube1.CubeWallpaper1" android:permission="android.permission.BIND_WALLPAPER">

<intent-filter>

<action android:name="android.service.wallpaper.WallpaperService"/>
</intent-filter>

<meta-data android:name="android.service.wallpaper" android:resource="@xml/cube1"/>
</service>
</application>
</manifest>
----------------------------------------------------------------------------------------------------------
package com.example.android.livecubes.cube1;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.os.SystemClock;
import android.service.wallpaper.WallpaperService;
import android.view.SurfaceHolder;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;

public class CubeWallpaper1 extends WallpaperService {

 private final Handler mHandler = new Handler();

 @Override
 public void onCreate() {
  super.onCreate();
  heroPictures();
 }

 @Override
 public void onDestroy() {
  super.onDestroy();
 }

 @Override
 public Engine onCreateEngine() {
  return new WPEngine();
 }

 class WPEngine extends Engine implements Runnable{

  private final Paint paint = new Paint();
  private int wpWidth;
  private int wpHeight;

  int XXX = 0;
  int YYY = 0;

  public void run() {
   mHandler.removeCallbacks(this);
   mHandler.postDelayed(this, 10);
   drawFrame();
   XXX = ( XXX + 11 ) % 470;
   YYY = ( YYY + 7 ) % 900;
  }

  private boolean mVisible;

  WPEngine() {
   mHandler.postDelayed(this, 10);
  }

  @Override
  public void onCreate(SurfaceHolder surfaceHolder) {
   super.onCreate(surfaceHolder);
  }

  @Override
  public void onDestroy() {
   super.onDestroy();
   mHandler.removeCallbacks(this);
  }

  @Override
  public void onVisibilityChanged(boolean visible) {
   try{
    mVisible = visible;
    if (visible) {
     drawFrame();
    }
   } catch (Exception e) {
   }
  }

  @Override
  public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
   super.onSurfaceChanged(holder, format, width, height);
   wpWidth = width;
   wpHeight = height;
   drawFrame();
  }

  @Override
  public void onSurfaceCreated(SurfaceHolder holder) {
   super.onSurfaceCreated(holder);
   drawFrame();
  }

  @Override
  public void onSurfaceDestroyed(SurfaceHolder holder) {
   super.onSurfaceDestroyed(holder);
   mVisible = false;
  }

  @Override
  public void onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels) {
   drawFrame();
  }

  void drawFrame( ) {
   final SurfaceHolder holder = getSurfaceHolder();

   Canvas canvas = null;
   try {
    canvas = holder.lockCanvas();
    if (canvas != null) {
     canvas.drawBitmap(bublickBitmap, XXX, 60 + YYY, paint);
                  }
   } finally {
    if (canvas != null) holder.unlockCanvasAndPost(canvas);
   }
  }
 }

 Bitmap bublickBitmap;

 void heroPictures() {
   bublickBitmap = BitmapFactory.decodeResource(getResources(), com.example.android.livecubes.R.drawable.bublick);
 }
}

No comments:

Post a Comment