【问题标题】:Code works on API 8 and can't on API 9 or 10代码适用于 API 8,但不能适用于 API 9 或 10
【发布时间】:2011-10-28 16:58:02
【问题描述】:

由于某种原因,我的代码非常适合 Froyo(API 8),但是当我尝试在 API 9 或 10 上运行它时,给我一个 Stopped Unexpectedly/Force Close 错误,AVD 和手机给我同样的错误消息。知道为什么吗? 我的审查代码:

所有页面看起来都类似于 ViewActivity.java。唯一的区别是被调用的drawable。

ViewActivity.java:

    import android.app.Activity;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;

    public class ViewActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //creates view
    TouchImageView img = new TouchImageView(this);
    //sets image
    Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.largeimage1);
    img.setImageBitmap(image);
    img.setMaxZoom(3f);
    setContentView(img); 
}
    //Creates the options menu
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.echooptions, menu);
    return true;
}
//Starts the chosen menu activity
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.back_item:
        Intent intentb = new Intent(this, page16.class);
        startActivity(intentb);
        return true;
    case R.id.next_item:
        Intent intentn = new Intent(this, page2.class);
        startActivity(intentn);
        return true;
    case R.id.about_menu_item:
        Intent intenta = new Intent(this, AboutActivity.class);
        startActivity(intenta);
        return true;
    case R.id.tablecontents:
        return true;
    case R.id.page1:
        Intent intent1 = new Intent(this, ViewActivity.class);
        startActivity(intent1);
        return true;
    case R.id.page2:
        Intent intent2 = new Intent(this, page2.class);
        startActivity(intent2);
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}
    }

TouchImageView.java:

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Matrix;
    import android.graphics.PointF;
    import android.view.MotionEvent;
    import android.view.ScaleGestureDetector;
    import android.view.View;
    import android.widget.ImageView;

    public class TouchImageView extends ImageView {

Matrix matrix = new Matrix();

// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;

// Remember some things for zooming
PointF last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 3f;
float[] m;

float redundantXSpace, redundantYSpace;

float width, height;
static final int CLICK = 3;
float saveScale = 1f;
float right, bottom, origWidth, origHeight, bmWidth, bmHeight;

ScaleGestureDetector mScaleDetector;

Context context;


public TouchImageView(Context context) {
    super(context);
    super.setClickable(true);
    this.context = context;
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    matrix.setTranslate(1f, 1f);
    m = new float[9];
    setImageMatrix(matrix);
    setScaleType(ScaleType.MATRIX);

    setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            mScaleDetector.onTouchEvent(event);

            matrix.getValues(m);
            float x = m[Matrix.MTRANS_X];
            float y = m[Matrix.MTRANS_Y];
            PointF curr = new PointF(event.getX(), event.getY());

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    last.set(event.getX(), event.getY());
                    start.set(last);
                    mode = DRAG;
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (mode == DRAG) {
                        float deltaX = curr.x - last.x;
                        float deltaY = curr.y - last.y;
                        float scaleWidth = Math.round(origWidth * saveScale);
                        float scaleHeight = Math.round(origHeight * saveScale);
                        if (scaleWidth < width) {
                            deltaX = 0;
                            if (y + deltaY > 0)
                                deltaY = -y;
                            else if (y + deltaY < -bottom)
                                deltaY = -(y + bottom); 
                        } else if (scaleHeight < height) {
                            deltaY = 0;
                            if (x + deltaX > 0)
                                deltaX = -x;
                            else if (x + deltaX < -right)
                                deltaX = -(x + right);
                        } else {
                            if (x + deltaX > 0)
                                deltaX = -x;
                            else if (x + deltaX < -right)
                                deltaX = -(x + right);

                            if (y + deltaY > 0)
                                deltaY = -y;
                            else if (y + deltaY < -bottom)
                                deltaY = -(y + bottom);
                        }
                        matrix.postTranslate(deltaX, deltaY);
                        last.set(curr.x, curr.y);
                    }
                    break;

                case MotionEvent.ACTION_UP:
                    mode = NONE;
                    int xDiff = (int) Math.abs(curr.x - start.x);
                    int yDiff = (int) Math.abs(curr.y - start.y);
                    if (xDiff < CLICK && yDiff < CLICK)
                        performClick();
                    break;

                case MotionEvent.ACTION_POINTER_UP:
                    mode = NONE;
                    break;
            }
            setImageMatrix(matrix);
            invalidate();
            return true; // indicate event was handled
        }

    });
}

@Override
public void setImageBitmap(Bitmap bm) { 
    super.setImageBitmap(bm);
    bmWidth = bm.getWidth();
    bmHeight = bm.getHeight();
}

public void setMaxZoom(float x)
{
    maxScale = x;
}

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        mode = ZOOM;
        return true;
    }

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        float mScaleFactor = (float)Math.min(Math.max(.95f, detector.getScaleFactor()), 1.05);
        float origScale = saveScale;
        saveScale *= mScaleFactor;
        if (saveScale > maxScale) {
            saveScale = maxScale;
            mScaleFactor = maxScale / origScale;
        } else if (saveScale < minScale) {
            saveScale = minScale;
            mScaleFactor = minScale / origScale;
        }
        right = width * saveScale - width - (2 * redundantXSpace * saveScale);
        bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
        if (origWidth * saveScale <= width || origHeight * saveScale <= height) {
            matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2);
            if (mScaleFactor < 1) {
                matrix.getValues(m);
                float x = m[Matrix.MTRANS_X];
                float y = m[Matrix.MTRANS_Y];
                if (mScaleFactor < 1) {
                    if (Math.round(origWidth * saveScale) < width) {
                        if (y < -bottom)
                            matrix.postTranslate(0, -(y + bottom));
                        else if (y > 0)
                            matrix.postTranslate(0, -y);
                    } else {
                        if (x < -right) 
                            matrix.postTranslate(-(x + right), 0);
                        else if (x > 0) 
                            matrix.postTranslate(-x, 0);
                    }
                }
            }
        } else {
            matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());
            matrix.getValues(m);
            float x = m[Matrix.MTRANS_X];
            float y = m[Matrix.MTRANS_Y];
            if (mScaleFactor < 1) {
                if (x < -right) 
                    matrix.postTranslate(-(x + right), 0);
                else if (x > 0) 
                    matrix.postTranslate(-x, 0);
                if (y < -bottom)
                    matrix.postTranslate(0, -(y + bottom));
                else if (y > 0)
                    matrix.postTranslate(0, -y);
            }
        }
        return true;

    }
}

@Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
{
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    width = MeasureSpec.getSize(widthMeasureSpec);
    height = MeasureSpec.getSize(heightMeasureSpec);
    //Fit to screen.
    float scale;
    float scaleX =  (float)width / (float)bmWidth;
    float scaleY = (float)height / (float)bmHeight;
    scale = Math.min(scaleX, scaleY);
    matrix.setScale(scale, scale);
    setImageMatrix(matrix);
    saveScale = 1f;

    // Center the image
    redundantYSpace = (float)height - (scale * (float)bmHeight) ;
    redundantXSpace = (float)width - (scale * (float)bmWidth);
    redundantYSpace /= (float)2;
    redundantXSpace /= (float)2;

    matrix.postTranslate(redundantXSpace, redundantYSpace);

    origWidth = width - 2 * redundantXSpace;
    origHeight = height - 2 * redundantYSpace;
    right = width * saveScale - width - (2 * redundantXSpace * saveScale);
    bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
    setImageMatrix(matrix);
}
    }

【问题讨论】:

    标签: android


    【解决方案1】:

    InstantiationException: mil.Army.page2 表示它无法创建类page2 的实例。我认为这通常在您尝试实例化抽象类或接口时抛出。根据this,它可以被抛出,因为该类没有默认(零参数)构造函数。我不知道为什么它只能在 API 8 上工作,因为这似乎是一个 Java 问题,但这似乎是一个可能的原因。

    编辑:也可以尝试简单地重建项目。在 Eclipse 中,只需转到 Project-&gt;Clean 即可清理它。

    编辑:我也遇到了这个,这似乎与 b 相关:

    Why do I get an InstantiationException if I try to start a service?

    【讨论】:

    • 根据这个问题,您可能正在硬编码标签而不是使用字符串资源:stackoverflow.com/questions/5740893/…
    • 仍然收到此错误:'10-28 14:45:17.827: ERROR/dalvikvm-heap(774): 8420100-byte external allocation too large for this process。 10-28 14:45:17.851: ERROR/GraphicsJNI(774​​): VM won't let us allocate 8420100 bytes' 感谢到目前为止 DeeV 的帮助。
    • 该消息可能意味着您正在分配一个很大的数组或对象(可能是图像)。您需要弄清楚一次在哪里分配大块,看看是否可以削减它。我希望我能告诉你为什么这只会影响以后的 API。理论上,如果一个程序在 API 8 中运行,它也可以在 API 9+ 中运行。
    • 我不喜欢理论的一个原因,它通常不会那样工作......但感谢您的帮助,如果我弄清楚了,我会发布我做了什么来解决它。感谢您抽出宝贵时间。
    • 好吧,我不知道这些 API 之间的功能差异是什么。我认为这可能类似于人们最近遇到的 API 14 问题,其中 R 文件中生成的 ID 不再声明为 final。他们这样做是为了更改 ID 号以防止与共享库发生冲突。 99% 的时间,它完全没有影响。但是,使用 ID 作为键的 Java switch 语句不再编译,每个人都必须将它们转换为 if-else 语句。我只是不是 100% 确定这是原因。
    猜你喜欢
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 2019-01-23
    • 2013-05-29
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多