如何在Android Studio中修复android按钮,抛出强制转换异常?

时间:2017-06-26 13:59:51

标签: android button casting

我的应用程序运行正常,直到我开始点击一个特定按钮rate-button。每次我单击此按钮,应用程序崩溃,我在log cat中收到此消息:

22808/com.nileworx.guesstheplace E/AndroidRuntime: FATAL EXCEPTION: main
                                                                        Process: com.nileworx.guesstheplace, PID: 22808
                                                                        java.lang.ClassCastException: com.nileworx.guesstheplace.GameActivity cannot be cast to com.nileworx.guesstheplace.MainActivity
                                                                            at com.nileworx.guesstheplace.CustomDialog$11.onClick(CustomDialog.java:283)
                                                                            at android.view.View.performClick(View.java:5198)
                                                                            at android.view.View$PerformClick.run(View.java:21147)
                                                                            at android.os.Handler.handleCallback(Handler.java:739)
                                                                            at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                            at android.os.Looper.loop(Looper.java:148)
                                                                            at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
06-25 06:46:03.423 1642-2032/system_process W/ActivityManager:   Force finishing activity com.nileworx.guesstheplace/.GameActivity

我认为gameactivity存在问题,只有一个错误:

@Override
protected void onResume() {
    super.onResume();

    if (!mSharedPreferences.getString("placesNum", "0").equals("0")) {
        String updatesDlgMsg = String.format(getResources().getString(R.string.updatesDlg), mSharedPreferences.getString("placesNum", "0"));
        dialog.showDialog(R.layout.blue_dialog, "updatesDlg", updatesDlgMsg, mSharedPreferences.getString("placesJSON", ""));
        e.putString("placesNum", "0");
        e.commit();
    }
}

第6行代码存在以下消息的问题:

  

格式化字符串' updatesDlg'不是有效的格式字符串,所以它应该   不能传递给String.format less ...(Ctrl + F1)如果字符串包含   a'%'字符,然后字符串可能是格式化字符串   从Java代码传递给String.format以替换每个'%'   具有特定值的事件。这个棉绒警告检查两个   相关问题:(1)格式化无效的字符串,意思是   尝试时,String.format将在运行时抛出异常   使用格式字符串。 (2)包含'%'的字符串那不是   格式化字符串传递给String.format调用。在这   案例'%'将需要作为' %%'进行转义。注意:并非所有字符串   看起来像格式化字符串是供...使用   的String.format;例如,它们可能包含用于的日期格式   android.text.format.Time#格式()。皮棉不能总是弄明白   String是一种日期格式,因此您可能会收到错误警告   场景。有关如何使用的信息,请参阅suppress help主题   在这种情况下抑制错误

我不知道如何解决这个问题,我已经尝试了2个多小时来解决它。

我的费率按钮代码

private void rateDlg(final Dialog dialog, final String marketLink) {

    Button rateBtn = (Button) dialog.findViewById(R.id.rateBtn);
    // if button is clicked, close the custom dialog
    rateBtn.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            sou.playSound(R.raw.buttons);
            dialog.dismiss();
            MainActivity mainAct = (MainActivity) context;
            Intent intent = new Intent(Intent.ACTION_VIEW);



            intent.setData(Uri.parse("playstorelink, changed for stackoverflow"));

            if (!mainAct.MyStartActivity(intent)) {
                // Market (Google play) app seems not
                // installed, let's try
                // to open a webbrowser
                intent.setData(Uri.parse("playstorelink, changed for stackoverflow"));
                if (!mainAct.MyStartActivity(intent)) {
                    // Well if this also fails, we have run
                    // out of options,
                    // inform the user.
                    Toast.makeText(context, "Could not open Android market, please install the market app.", Toast.LENGTH_SHORT).show();
                } else {
                    editor.putInt("usingNum", 100);
                    editor.commit();
                }
            } else {
                editor.putInt("usingNum", 100);
                editor.commit();
            }
        }
    });

    Button laterBtn = (Button) dialog.findViewById(R.id.laterBtn);
    // if button is clicked, close the custom dialog
    laterBtn.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            sou.playSound(R.raw.buttons);
            editor.putInt("usingNum", 0);
            editor.commit();
            dialog.dismiss();
        }
    });
}

1 个答案:

答案 0 :(得分:2)

首先检查Strings资源文件中是否存在R.string.updatesDlg

你的另一个问题是由错误GameActivity cannot be cast to com.nileworx.guesstheplace.MainActivity所述的错误演员造成的,你试图将一个类投射到另一个类。您的按钮对话框代码显示此处...

MainActivity mainAct = (MainActivity) context;

我非常确定context在这种情况下不属于MainActivity类型。检查context的类型。错误表明它的类型为GameActivity

话虽如此,我不明白为什么你需要伸出MainActivity,除非那里发生了特别的事情。您可以创建一个Helper类,并包含一个检查是否已安装包的方法。你传递了你的活动的背景。像这样:

//MainActivity mainAct = (MainActivity) context;
//Intent intent = new Intent(Intent.ACTION_VIEW);
//intent.setData(Uri.parse("playstorelink, changed for stackoverflow"));

if (!isPackageInstalled(playstorelink)) {
    // Market (Google play) app seems not
    // installed, let's try
    // to open a webbrowser
    //intent.setData(Uri.parse("playstorelink, changed for stackoverflow"));
    if (!isPackageInstalled(playstorelink)) {
        Toast.makeText(context, "Could not open Android market, please install the market app.", Toast.LENGTH_SHORT).show();
    } else {
        editor.putInt("usingNum", 100);
        editor.commit();
    }
} else {
    editor.putInt("usingNum", 100);
    editor.commit();
}

private boolean isPackageInstalled(Context context, String packagename) {
    try {
        context.packageManager.getPackageInfo(packagename, 0);
        return true;
    } catch (NameNotFoundException e) {
        return false;
    }
}

在旁注中,这行代码使我相信您将活动的实例保存为静态变量:

if (!mainAct.MyStartActivity(intent)) {

这非常糟糕!我将引用这个answer -

  

不要将Context存储在硬引用中。或者你会泄漏   记忆。活动引用了View和众多其他活动   的东西。如果存储上下文,则存储活动和   事情变坏了。学习传递Context,使用   尽可能的应用程序上下文以及是否需要传递它   周围,​​这是有充分理由的。大多数时候App上下文   足以获得资源,字符串等。如果你要去   存储Context,始终存储context.getApplicationContext();决不   存储静态活动上下文。你也可以google这个   StackOverflow有一些很好的答案。

您可以使用事件系统库(如EventBus)在活动/片段之间进行通信,而不是将上下文存储在静态变量中。您也可以将上下文从一个地方传递到另一个地方,或使用意图putExtras将数据添加到意图中,然后在另一个活动/对话框中接收...