Java OutOfMemory 异常无法在 Lollipop 之前的设备上启动应用程序

标签 java android

当我尝试在 Nexus 5 (Android 6 M) 上启动我的应用程序时,一切正常,但当我尝试从 Galaxy S4 (4.4) 或其他 Kitkat 设备或模拟器启动它时,我的应用程序崩溃了白屏,然后崩溃,或者立即崩溃。

Android 监视器:

11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime: FATAL EXCEPTION: main
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime: Process: com.iotech.discover, PID: 12397
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime: java.lang.OutOfMemoryError
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:677)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:507)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:872)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.content.res.Resources.loadDrawable(Resources.java:3024)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.content.res.Resources.getDrawable(Resources.java:1586)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.view.Window.setBackgroundDrawableResource(Window.java:1035)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at com.iotech.discover.LoginActivity.onCreate(LoginActivity.java:50)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.app.Activity.performCreate(Activity.java:5426)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.app.ActivityThread.access$900(ActivityThread.java:161)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:157)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5356)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:515)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
11-03 14:28:48.536 12397-12397/com.iotech.discover E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method)

我认为这是因为我使用了位图背景,但由于我有 4 个不同的错误,所以我不知道它来自哪里,而且它之前一直有效。

编辑:我的可绘制对象位于可绘制文件夹中,这是我的主要 Activity :

public class LoginActivity extends AppCompatActivity {
    private static final String TAG = "LoginActivity";
    private static final int REQUEST_SIGNUP = 0;

    @InjectView(R.id.input_email)
    EditText _emailText;
    @InjectView(R.id.input_password)
    EditText _passwordText;
    @InjectView(R.id.btn_login)
    Button _loginButton;
    @InjectView(R.id.link_signup)
    TextView _signupLink;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        getWindow().setBackgroundDrawableResource(R.drawable.mlogin_paris_aerian);
        ButterKnife.inject(this);

        if (!isInternetConnected()) {
            alertDialogNoInternet();
        }

        _loginButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                login();
            }
        });

        _signupLink.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // Start the Signup activity
                Intent intent = new Intent(getApplicationContext(), SignupActivity.class);
                startActivityForResult(intent, REQUEST_SIGNUP);
            }
        });
    }

    public void login() {
        Log.d(TAG, "Login");

        if (!validate()/* || !isConnected()*/) {
            onLoginFailed();
            return;
        }

        _loginButton.setEnabled(false);

        final ProgressDialog progressDialog = new ProgressDialog(LoginActivity.this,
                R.style.AppTheme_Dark_Dialog);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage(getString(R.string.login_authentication));
        progressDialog.show();

        String email = _emailText.getText().toString();
        String password = _passwordText.getText().toString();

        // TODO : onLoginSuccess si auth ok côté serveur
        Context context = getApplicationContext();
        loginAPI(context, email, password);

    public boolean isInternetConnected(){
        ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Activity.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected())
            return true;
        else
            return false;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_SIGNUP) {
            if (resultCode == RESULT_OK) {

                // TODO: Implement successful signup logic here
                // By default we just finish the Activity and log them in automatically
                this.finish();
            }
        }
    }

    @Override
    public void onBackPressed() {
        // Disable going back to the MainActivity
        moveTaskToBack(true);
    }

    public void onLoginSuccess() {
        _loginButton.setEnabled(true);
        finish();
    }

    public void onLoginFailed() {
        Toast.makeText(getBaseContext(), R.string.login_failed, Toast.LENGTH_LONG).show();

        _loginButton.setEnabled(true);
    }

    public boolean validate() {
        boolean valid = true;

        String email = _emailText.getText().toString();
        String password = _passwordText.getText().toString();
        onLoginSuccess();
        return valid;
    }

    public void alertDialogNoInternet (){
        AlertDialog.Builder builder1 = new AlertDialog.Builder(this);
        builder1.setTitle(getString(R.string.nointernet_title));
        builder1.setMessage(getString(R.string.nointernet_message));
        builder1.setCancelable(true);
        builder1.setPositiveButton(getString(R.string.ok),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        Toast.makeText(getApplicationContext(),
                                "Merci", Toast.LENGTH_SHORT)
                                .show();
                        //dialog.cancel();
                    }
                });
        builder1.setNegativeButton(getString(R.string.cancel),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });

        AlertDialog alert11 = builder1.create();
        alert11.show();
    }

    public static void loginAPI (Context context, final String mail, final String password) {
        JSONObject obj = new JSONObject();
        try {
            obj.put("email", mail);
            obj.put("password", password);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        RequestQueue queue = Volley.newRequestQueue(context);
        JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, "http://46.101.218.111/api/v1/auth",obj,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        System.out.println(response);
                        //hideProgressDialog();
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        //hideProgressDialog();
                        System.out.println(error);
                    }
                });
        queue.add(jsObjRequest);
    }
}

最佳答案

将导致崩溃的drawable放在drawable-xxhdpi或drawable-xhdpi中(选择更适合您的图像的文件夹)。

可能您的图像已经是高分辨率的,但由于它被放置在可绘制中,因此它被视为 mdpi 图像,并且操作系统会对其进行缩放。

请记住,图像大小(以 KB 为单位)并不是内存消耗的主要因素。

关于Java OutOfMemory 异常无法在 Lollipop 之前的设备上启动应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33500499/

相关文章:

android - Pixate 按钮阴影 Android

java - 使用 Soot 分析 Android 应用程序

android - 如何获取重力传感器信息?

android - 在 Android 开发人员控制台上重复使用扩展文件

java - 朱尼特 2.0 : Different results for same test

java - 从 Java 发送到 JNI 的参数未发送

java - Java 中的 IP header

java - 更正我从 SimpleDateFormat 输出的日期

java - 为什么我在解析 xml 文件时遇到 fatal error ?

android - 如何在 Android 中的 FloatingActionButton 上方添加 TextView