我的应用程序运行正常,直到我开始点击一个特定按钮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();
}
});
}
答案 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
将数据添加到意图中,然后在另一个活动/对话框中接收...