Я делаю приложение с живыми обоями для андроида. Я использую libgdx для графики. Я скачал тестовое приложение с github. Приложение работает нормально на большинстве устройств, но не на моем Huawei. Он вылетает без исключения, как только приложение запускается. Я окружил весь рабочий код ловушками для попыток, но он не может поймать никаких исключений, поэтому я предполагаю, что это не связано с кодом. На всякий случай выложу код, который использую:
Слушатель приложения:
public class GDXTestPaper implements ApplicationListener {
public static float SQRT2;
// private ParticleEffect effect;
public int width, height;
public Vector2 touchPosition;
public Vector3 touchPosition3;
public ArrayList<Firefly> flies;
public ArrayList<Swarm> swarms;
private OrthographicCamera camera;
private SpriteBatch batch;
private Texture texture;
private int flyCount = 500;
// private MeshHelper meshHelper;
private int swarmCount = 5;
private boolean updateScreen = false;
@Override
public void create() {
try {
touchPosition = new Vector2();
touchPosition3 = new Vector3();
SQRT2 = (float) Math.sqrt(2);
width = Gdx.graphics.getWidth();
height = Gdx.graphics.getHeight();
camera = new OrthographicCamera(1, height / width);
batch = new SpriteBatch();
texture = new Texture(Gdx.files.internal("data/firefly.png"));
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
TextureRegion region = new TextureRegion(texture, 0, 0, 64, 64);
batch.enableBlending();
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE);
batch.setProjectionMatrix(camera.combined);
flies = new ArrayList<Firefly>();
for (int i = 0; i < flyCount; i++) {
try{
Firefly f = new Firefly(this, region);
flies.add(f);
} catch (GdxRuntimeException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
}
swarms = new ArrayList<Swarm>();
for (int i = 0; i <= swarmCount; i++) {
try{
Swarm s = new Swarm(this);
swarms.add(s);
} catch (GdxRuntimeException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
}
} catch (GdxRuntimeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void dispose() {
batch.dispose();
texture.dispose();
// meshHelper.dispose();
}
@Override
public void render() {
try {
// Gdx.gl.glClearColor(0, 0, 0, 1);
// Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (Gdx.graphics.isGL20Available()) {
Gdx.graphics.getGL20().glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
Gdx.graphics.getGL20().glClear(GL10.GL_COLOR_BUFFER_BIT);
} else {
Gdx.gl.glClearColor(0, 0, 0, 0.1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
}
batch.setProjectionMatrix(camera.combined);
// Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
Gdx.gl.glEnable(GL10.GL_BLEND);
Gdx.gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glViewport(0, 0, width, height);
if (updateScreen) {
updateScreen = false;
camera.setToOrtho(false, width, height);
batch.setProjectionMatrix(camera.combined);
// effect.setPosition(width/2, height/2);
}
camera.update();
// effect.update(Gdx.graphics.getDeltaTime()/1.6f);
//Process touch
if (Gdx.input.isTouched()) {
touchPosition3.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPosition3);
touchPosition.set(touchPosition3.x, touchPosition3.y);
//camera.unproject(touchPosition);
} else {
touchPosition.set(-1, -1);
}
batch.begin();
// effect.draw(batch);
// sprite.draw(batch);
// batch.draw(texture, 10, 10);
// batch.draw(texture, 50, 50);
// batch.draw(texture, 100, 100);
float delta = Gdx.graphics.getDeltaTime();
for (Firefly fly : flies) {
try {
fly.move(delta);
fly.render(batch);
} catch (GdxRuntimeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
for (Swarm swarm : swarms) {
try {
swarm.move(delta);
} catch (GdxRuntimeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
batch.end();
} catch (GdxRuntimeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void resize(int width, int height) {
this.width = width;
this.height = height;
updateScreen = true;
}
@Override
public void pause() {
}
@Override
public void resume() {
}
}
Основная деятельность:
public class MainActivity extends AndroidApplication {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
cfg.useGL20 = true;
cfg.getTouchEventsForLiveWallpaper = true;
initialize(new GDXTestPaper(), cfg);
System.out.println("gdx initialized");
} catch (GdxRuntimeException e) {
e.printStackTrace();
}
}
}
Класс Firefly:
public class Firefly {
public Vector2 position;
public Vector2 velocity;
public Vector2 acceleration;
public FireflyState state = FireflyState.ALIVE;
public boolean visible = true;
private float speedLimit = 60;
private float gravityForce = 6.2f;
private float alpha = 1f; // How bright are we
private Sprite sprite;
private GDXTestPaper stage;
Firefly(GDXTestPaper stage, TextureRegion region) {
try {
this.stage = stage;
// Create sprite
sprite = new Sprite(region);
sprite.setSize(32f, 32f);
// Origin central to sprite
sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2);
// sprite.setPosition(100,10);
Random rnd = new Random();
// Init Position
position = new Vector2(rnd.nextFloat() * stage.width, rnd.nextFloat()
* stage.height);
// Each firefly has randomly generated traits:
speedLimit = rnd.nextFloat() * 30 + 10;
// How attracted from a swarm
gravityForce = rnd.nextFloat() * 10f;
// position.set(rnd.nextFloat() * stage.width, rnd.nextFloat() *
// stage.height);
// position.set(30,50);
// velocity = new Vector2(rnd.nextFloat() - 0.5f * 10,
// rnd.nextFloat() - 0.5f * 10);
velocity = new Vector2(0, 0);
acceleration = new Vector2(0f, 0f);
} catch (GdxRuntimeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
void create() {
}
void move(float delta) {
try {
switch (state) {
case FADING:
if (this.alpha > 0f) {
this.alpha -= 0.1f;
} else {
alpha = 0f;
state = FireflyState.HIDING;
}
break;
case GLOWING:
if (this.alpha < 1f) {
this.alpha += 0.01f;
} else {
alpha = 1f;
state = FireflyState.ALIVE;
}
break;
case ALIVE:
alpha = 1f;
// Flyin' around minding our own business. Should we start fading?
if (Math.random() > 0.999) {
state = FireflyState.FADING;
}
break;
case HIDING:
alpha = 0f;
// We're flying around invisible at the moment. Should we light back
// up?
if (Math.random() > 0.999) {
state = FireflyState.GLOWING;
}
break;
default:
break;
}
// Should we turn on/off our light?
acceleration.set(0f, 0f);
acceleration.x += (float) (Math.random() - 0.5);
acceleration.y += (float) (Math.random() - 0.5);
// Screen edge bouncing
if (position.x + velocity.x > stage.width - 2
|| position.x + velocity.x < 0) {
// velocity.x = -velocity.x;
velocity.x = 0;
}
// Screen edge bouncing
if (position.y + velocity.y > stage.height - 2
|| position.y + velocity.y < 0) {
// velocity.y = -velocity.y;
velocity.y = 0;
}
velocity.add(acceleration);
// Check touch gravity
if (stage.touchPosition.x != -1) {
// Active touch. Apply gravity, ignore swarms.
float force = 10000 / this.position.dst2(stage.touchPosition);
//this.velocity.x = force;
//this.velocity.y = 0;
//this.velocity.setAngle(angle)
this.velocity.x += force
* (stage.touchPosition.x - this.position.x);
this.velocity.y += force
* (stage.touchPosition.y - this.position.y);
} else {
// Gravity to swarms
for (Swarm swarm : stage.swarms) {
try {
float dist = this.fastDistance(swarm.position);
if (dist > 1 && dist < 200) {
float force = (gravityForce / dist) * delta;
this.velocity.x += force
* (swarm.position.x - this.position.x);
this.velocity.y += force
* (swarm.position.y - this.position.y);
// System.out.println(this.acceleration.x);
}
} catch (GdxRuntimeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
// }
// If we start moving off the screen, strong force to push us back.
if (position.x > stage.width || position.x < 0) {
velocity.x = stage.width / 2 - position.x;
}
if (position.y > stage.height || position.y < 0) {
velocity.y = stage.height / 2 - position.y;
// position.y = stage.height / 2;
}
// Speed limiting
if (velocity.x > speedLimit)
velocity.x = speedLimit;
if (velocity.x < -speedLimit)
velocity.x = -speedLimit;
if (velocity.y > speedLimit)
velocity.y = speedLimit;
if (velocity.y < -speedLimit)
velocity.y = -speedLimit;
// position.add(velocity);
position.x += velocity.x * delta;
position.y += velocity.y * delta;
} catch (GdxRuntimeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
void render(SpriteBatch batch) {
try {
alpha = Math.min(1f, alpha);
alpha = Math.max(0f, alpha);
if (state != FireflyState.HIDING) {
sprite.setColor(0.5f, 1f, 0.5f, alpha);
sprite.setPosition(position.x, position.y);
sprite.setRotation(velocity.angle() - 90); // Texture rotated by 90
// degrees
sprite.draw(batch);
}
} catch (GdxRuntimeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
void dispose() {
}
float fastDistance(Vector2 target) {
try {
float abX = Math.abs(position.x - target.x);
float abY = Math.abs(position.y - target.y);
float dist = (float) ((1 + 1 / (4 - 2 * GDXTestPaper.SQRT2)) / 2 * Math
.min((1 / GDXTestPaper.SQRT2) * (abX + abY), Math.max(abX, abY)));
return dist;
} catch (GdxRuntimeException e) {
e.printStackTrace();
return -1;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
public enum FireflyState {
GLOWING, FADING, ALIVE, HIDING
}
}
Класс роя:
public class Swarm {
private static final float SPEED_LIMIT = 60;
public Vector2 position;
public Vector2 velocity;
public Vector2 acceleration;
private GDXTestPaper stage;
Swarm(GDXTestPaper stage) {
try{
this.stage = stage;
Random rnd = new Random();
// Init Position
position = new Vector2(rnd.nextFloat() * stage.width, rnd.nextFloat()
* stage.height);
velocity = new Vector2(0, 0);
acceleration = new Vector2(0f, 0f);
} catch (GdxRuntimeException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
}
void move(float delta) {
try{
acceleration.set(0f, 0f);
acceleration.x += (float) (Math.random() - 0.5) * 8;
acceleration.y += (float) (Math.random() - 0.5) * 8;
// Screen edge bouncing
if (position.x + velocity.x > stage.width - 2
|| position.x + velocity.x < 0) {
// velocity.x = -velocity.x;
velocity.x = 0;
}
// Screen edge bouncing
if (position.y + velocity.y > stage.height - 2
|| position.y + velocity.y < 0) {
// velocity.y = -velocity.y;
velocity.y = 0;
}
velocity.add(acceleration);
// }
// Speed limiting
if (velocity.x > SPEED_LIMIT)
velocity.x = SPEED_LIMIT;
if (velocity.x < -SPEED_LIMIT)
velocity.x = -SPEED_LIMIT;
if (velocity.y > SPEED_LIMIT)
velocity.y = SPEED_LIMIT;
if (velocity.y < -SPEED_LIMIT)
velocity.y = -SPEED_LIMIT;
// position.add(velocity);
position.x += velocity.x * delta;
position.y += velocity.y * delta;
// Reposition on stage if we get lost
if (position.x > stage.width || position.x < 0) {
position.x = stage.width / 2;
}
if (position.y > stage.height || position.y < 0) {
position.y = stage.height / 2;
}
} catch (GdxRuntimeException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
}
}
Журнал сбоев:
I / art: Позднее включение -Xcheck: jni net.precariouspanther.gdxtest E / HAL: load: id = gralloc! = Hmi-> id = gralloc
net.precariouspanther.gdxtest I / BD.Reporter: com.huawei.bd.IBDService$Stub$Proxy@845e756
net.precariouspanther.gdxtest I / System.out: gdx инициализирован
net.precariouspanther.gdxtest I / AndroidInput: настройка приемника датчика
net.precariouspanther.gdxtest I / HwSecImmHelper: mSecurityInputMethodService имеет значение null
/net.precariouspanther.gdxtest E / HAL: load: id = gralloc! = hmi-> id = gralloc
net.precariouspanther.gdxtest I / OpenGLRenderer: Инициализированный EGL, версия 1.4
net.precariouspanther.gdxtest W / OpenGLRenderer: load: so = / system / lib / libhwuibp.so Ошибка dlopen: библиотека "/system/lib/libhwuibp.so" не найдена
/net.precariouspanther.gdxtest W / OpenGLRenderer: инициализировать кэш двоичной программы: сбой загрузки
/net.precariouspanther.gdxtest E / HAL: load: id = gralloc! = hmi-> id = gralloc
/net.precariouspanther.gdxtest W / GL2JNIView: создание контекста OpenGL ES 2.0
/net.precariouspanther.gdxtest I / AndroidInput: отключение приемника датчика
/net.precariouspanther.gdxtest I / Process: отправка сигнала. PID: 26810 SIG: 9
Заранее спасибо.