- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将 AdMob ID 从 JsonData 获取到我的应用中,以便将来可以更改它。
我的愿景:
JSON
文件将上传到我的服务器,其链接将位于应用程序内部。在 json 文件中找到的 AdMob ID 应在应用程序 adUnitID 中使用。到目前为止,我已经做到了:
String jsonToProcess = "https://drive.google.com/uc?id=113RUepiYecy5pBwj-t4BtBXwlQwgf-dU";
String interstialAd = new JsonParser().parse(jsonToProcess).getAsJsonObject()
.get("response").getAsJsonObject()
.get("Interstial AD").getAsString();
mInterstitialAd = new InterstitialAd(getActivity());
mInterstitialAd.setAdUnitId(interstialAd);
mInterstitialAd.loadAd(new AdRequest.Builder().build());
mInterstitialAd.setAdListener(new AdListener() {
@Override
public void onAdClosed() {
// Load the next interstitial.
Toast.makeText(getActivity(), "Thank you for supporting us, kind mate :)",
Toast.LENGTH_LONG).show();
mInterstitialAd.loadAd(new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR).build());
}
});
这是我的 json 文件:
{
"response": {
"Interstial AD": "ca-app-pub-3940256099942544/1033173712"
}
}
问题是,它不仅不起作用,而且还导致我的应用程序崩溃并出现以下错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.domian.app/com.domain.app.MainActivity}: com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 7 path $
编辑:新日志:
Stack :
==============
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:117)
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105)
at java.net.InetAddress.getAllByName(InetAddress.java:1154)
at com.android.okhttp.Dns$1.lookup(Dns.java:39)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175)
at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:244)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:26)
at java.net.URL.openStream(URL.java:1073)
at com.arewang.app.SettingsFragment.readFileFromServer(SettingsFragment.java:292)
at com.arewang.app.SettingsFragment.onCreate(SettingsFragment.java:85)
at android.support.v4.app.Fragment.performCreate(Fragment.java:2414)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1418)
at android.support.v4.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1195)
at android.support.v4.app.FragmentTransition.calculateFragments(FragmentTransition.java:1078)
at android.support.v4.app.FragmentTransition.startTransitions(FragmentTransition.java:117)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2408)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2243)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:654)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:168)
at com.duolingo.open.rtlviewpager.DelegatingPagerAdapter.finishUpdate(DelegatingPagerAdapter.java:61)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1244)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1092)
at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:540)
at com.duolingo.open.rtlviewpager.RtlViewPager.setAdapter(RtlViewPager.java:78)
at com.arewang.app.MainActivity.menuItemClicked(MainActivity.java:309)
at com.arewang.app.drawer.SimpleAbstractMenu.lambda$add$0(SimpleAbstractMenu.java:40)
at com.arewang.app.drawer.-$$Lambda$SimpleAbstractMenu$yY6riFac_ZFnhulwIN4yIqXEIMk.onMenuItemClick(Unknown Source:6)
at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:154)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:991)
at android.support.design.internal.NavigationMenuPresenter$1.onClick(NavigationMenuPresenter.java:352)
at android.view.View.performClick(View.java:6669)
at android.view.View.performClickInternal(View.java:6638)
at android.view.View.access$3100(View.java:789)
at android.view.View$PerformClick.run(View.java:26145)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6863)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
我的 fragment 完整代码:
public class SettingsFragment extends PreferenceFragment implements
BillingProcessor.IBillingHandler {
//You can change this setting if you would like to disable rate-my-app
boolean HIDE_RATE_MY_APP = false;
private BillingProcessor bp;
private Preference preferencepurchase;
private AlertDialog dialog;
private static String PRODUCT_ID_BOUGHT = "item_1_bought";
public static String SHOW_DIALOG = "show_dialog";
private InterstitialAd mInterstitialAd;
private static String fileUrl = "https://drive.google.com/uc?id=113RUepiYecy5pBwj-t4BtBXwlQwgf-dU";
// Firebase
private FirebaseAnalytics mFirebaseAnalytics;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.activity_settings);
setHasOptionsMenu(true);
getContext().getTheme().applyStyle(R.style.PreferencesTheme, true);
getActivity().getTheme().applyStyle(R.style.PreferencesTheme, true);
mFirebaseAnalytics = FirebaseAnalytics.getInstance(getActivity());
mFirebaseAnalytics.setCurrentScreen(getActivity(),"Settings Screen", null );
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().getWindow().setNavigationBarColor(getResources().getColor(R.color.myNavigationColor));
}
String interstialAd = new JsonParser().parse(readFileFromServer(fileUrl)).getAsJsonObject()
.get("response").getAsJsonObject()
.get("Interstial AD").getAsString();
mInterstitialAd = new InterstitialAd(getActivity());
mInterstitialAd.setAdUnitId(interstialAd);
mInterstitialAd.loadAd(new AdRequest.Builder().build());
mInterstitialAd.setAdListener(new AdListener() {
@Override
public void onAdClosed() {
// Load the next interstitial.
Toast.makeText(getActivity(), "Thank you for supporting us, kind mate :)",
Toast.LENGTH_LONG).show();
mInterstitialAd.loadAd(new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR).build());
}
});
// donate
Preference preferencerate = findPreference("donate");
preferencerate
.setOnPreferenceClickListener(preference -> {
CFAlertDialog.Builder builder = new CFAlertDialog.Builder(getContext())
.setDialogStyle(CFAlertDialog.CFAlertStyle.ALERT)
.setDialogBackgroundColor(Color.parseColor("#0c0c0c"))
.setHeaderView(R.layout.support_donate_layout)
.addButton("Cancel", Color.parseColor("#0c0c0c"), Color.parseColor("#FFFFFF"), CFAlertDialog.CFAlertActionStyle.DEFAULT, CFAlertDialog.CFAlertActionAlignment.JUSTIFIED, (dialog, which) -> {
Toast.makeText(getActivity(), "Hopefully some day you will ;)", Toast.LENGTH_LONG).show();
dialog.dismiss();
})
.addButton("Go Ahead", Color.parseColor("#FFFFFF"), Color.parseColor("#008248"), CFAlertDialog.CFAlertActionStyle.POSITIVE, CFAlertDialog.CFAlertActionAlignment.JUSTIFIED, (dialog, which) -> {
showAD();
dialog.dismiss();
});
builder.show();
return true;
});
Preference preferencefeed = findPreference("feedback");
preferencefeed
.setOnPreferenceClickListener(preference -> {
String deviceInfo="YOUR TEXT (Edit this) \n\n\n------------ Device Info ------------";
deviceInfo += "\n Android Version: " + android.os.Build.VERSION.RELEASE;
deviceInfo += "\n API Level: " + android.os.Build.VERSION.SDK_INT;
deviceInfo += "\n Device: " + android.os.Build.DEVICE;
deviceInfo += "\n Board: " + android.os.Build.BOARD;
deviceInfo += "\n Hardware: " + android.os.Build.HARDWARE;
deviceInfo += "\n Build ID: " + android.os.Build.ID;
deviceInfo += "\n Device Brand: " + android.os.Build.BRAND;
deviceInfo += "\n Device Manufacturer: " + android.os.Build.MANUFACTURER;
deviceInfo += "\n Model (and Product): " + android.os.Build.MODEL + " ("+ android.os.Build.PRODUCT + ")";
deviceInfo += "\n App Version: " + BuildConfig.VERSION_NAME;
deviceInfo += "\n ---------------------------------------------";
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto","info@domain.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "App Feedback");
emailIntent.putExtra(Intent.EXTRA_TEXT, deviceInfo);
startActivity(Intent.createChooser(emailIntent, "Send using:"));
return true;
});
Preference preferenceTweet = findPreference("tweet");
preferenceTweet
.setOnPreferenceClickListener(preference -> {
CFAlertDialog.Builder builder = new CFAlertDialog.Builder(getContext())
.setDialogStyle(CFAlertDialog.CFAlertStyle.ALERT)
.setDialogBackgroundColor(Color.parseColor("#0c0c0c"))
.setHeaderView(R.layout.support_footer_layout)
.addButton("Cancel", Color.parseColor("#0c0c0c"), Color.parseColor("#FFFFFF"), CFAlertDialog.CFAlertActionStyle.DEFAULT, CFAlertDialog.CFAlertActionAlignment.JUSTIFIED, (dialog, which) -> {
Toast.makeText(getActivity(), "Hopefully some day you will ;)", Toast.LENGTH_LONG).show();
dialog.dismiss();
})
.addButton("Tweet", Color.parseColor("#FFFFFF"), Color.parseColor("#008248"), CFAlertDialog.CFAlertActionStyle.POSITIVE, CFAlertDialog.CFAlertActionAlignment.JUSTIFIED, (dialog, which) -> {
shareTwitter();
Toast.makeText(getActivity(), "Thank you for your support, kind mate :)", Toast.LENGTH_LONG).show();
dialog.dismiss();
});
builder.show();
return true;
});
Preference preferencelicenses = findPreference("gitlicenses");
preferencelicenses
.setOnPreferenceClickListener(preference -> {
new LicenserDialog(getContext(), R.style.AlertDialogStyle)
.setTitle("Licenses")
.setCustomNoticeTitle("Files:")
.setBackgroundColor(Color.BLACK)
.setLibrary(new Library("Android Support Libraries",
"https://developer.android.com/topic/libraries/support-library/index.html",
License.APACHE))
.setLibrary(new Library("jsoup Library",
"https://github.com/jhy/jsoup",
License.MIT))
.setLibrary(new Library("Picasso Library",
"https://github.com/square/picasso",
License.APACHE))
.setLibrary(new Library("PhotoView Library",
"https://github.com/chrisbanes/PhotoView",
License.APACHE))
.setLibrary(new Library("Calligraphy Library",
"https://github.com/chrisjenx/Calligraphy",
License.APACHE))
.setLibrary(new Library("Android Material Intro Screen Library",
"https://github.com/TangoAgency/material-intro-screen",
License.MIT))
.setLibrary(new Library("AppUpdater Library",
"https://github.com/javiersantos/AppUpdater",
License.APACHE))
.setLibrary(new Library("CFAlertDialog Library",
"https://github.com/Codigami/CFAlertDialog",
License.MIT))
.setLibrary(new Library("NoPermission Library",
"https://github.com/NoNews/NoPermission",
License.APACHE))
.setLibrary(new Library("Material About Library",
"https://github.com/jrvansuita/MaterialAbout",
License.MIT))
.setLibrary(new Library("Unsplash",
"https://unsplash.com",
License.CREATIVE_COMMONS))
.setLibrary(new Library("Flaticon",
"https://www.flaticon.com/",
License.CREATIVE_COMMONS))
.setLibrary(new Library("Licenser",
"https://github.com/marcoscgdev/Licenser",
License.MIT))
.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
// TODO: 11/02/2018
})
.show();
return true;
});
if (Config.HIDE_DRAWER || !Config.DRAWER_OPEN_START) {
PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference("preferenceScreen");
Preference preferencedraweropen = findPreference("menuOpenOnStart");
preferenceScreen.removePreference(preferencedraweropen);
}
// purchase
preferencepurchase = findPreference("purchase");
String license = getResources().getString(R.string.google_play_license);
if (null != license && !license.equals("")){
bp = new BillingProcessor(getActivity(),
license, this);
bp.loadOwnedPurchasesFromGoogle();
preferencepurchase
.setOnPreferenceClickListener(preference -> {
bp.purchase(getActivity(), PRODUCT_ID());
return true;
});
if (getIsPurchased(getActivity())){
preferencepurchase.setIcon(R.drawable.ic_action_action_done);
}
} else {
PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference("preferenceScreen");
PreferenceCategory billing = (PreferenceCategory) findPreference("billing");
preferenceScreen.removePreference(billing);
}
String[] extra = getArguments().getStringArray(MainActivity.FRAGMENT_DATA);
if (null != extra && extra.length != 0 && extra[0].equals(SHOW_DIALOG)){
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Add the buttons
builder.setPositiveButton(R.string.settings_purchase, (dialog, id) -> bp.purchase(getActivity(), PRODUCT_ID()));
builder.setNegativeButton(R.string.cancel, (dialog, id) -> {
// User cancelled the dialog
});
builder.setTitle(getResources().getString(R.string.dialog_purchase_title));
builder.setMessage(getResources().getString(R.string.dialog_purchase));
// Create the AlertDialog
dialog = builder.create();
dialog.show();
}
if (HIDE_RATE_MY_APP){
PreferenceCategory other = (PreferenceCategory) findPreference("other");
Preference preference = findPreference("rate");
other.removePreference(preference);
}
}
public String readFileFromServer(String fileUrl) {
String fileContent;
try {
URL url = new URL(fileUrl);
return new Scanner(url.openStream()).useDelimiter("\\A").next();
} catch (IOException e) {
throw new RuntimeException("Error while trying to read file from server!", e);
}
}
@Override
public void onBillingInitialized() {
/*
* Called when BillingProcessor was initialized and it's ready to
* purchase
*/
}
@Override
public void onProductPurchased(String productId, TransactionDetails details) {
if (productId.equals(PRODUCT_ID())){
setIsPurchased(true, getActivity());
preferencepurchase.setIcon(R.drawable.ic_action_action_done);
Toast.makeText(getActivity(), getResources().getString(R.string.settings_purchase_success), Toast.LENGTH_LONG).show();
}
Log.v("INFO", "Purchase purchased");
}
@Override
public void onBillingError(int errorCode, Throwable error) {
Toast.makeText(getActivity(), getResources().getString(R.string.settings_purchase_fail), Toast.LENGTH_LONG).show();
Log.v("INFO", "Error");
}
@Override
public void onPurchaseHistoryRestored() {
if (bp.isPurchased(PRODUCT_ID())){
setIsPurchased(true, getActivity());
Log.v("INFO", "Purchase actually restored");
preferencepurchase.setIcon(R.drawable.ic_action_action_done);
if (dialog != null) dialog.cancel();
Toast.makeText(getActivity(), getResources().getString(R.string.settings_restore_purchase_success), Toast.LENGTH_LONG).show();
}
Log.v("INFO", "Purchase restored called");
}
public void setIsPurchased(boolean purchased, Context c){
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(c);
SharedPreferences.Editor editor= prefs.edit();
editor.putBoolean(PRODUCT_ID_BOUGHT, purchased);
editor.apply();
}
public static boolean getIsPurchased(Context c){
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(c);
boolean prefson = prefs.getBoolean(PRODUCT_ID_BOUGHT, false);
return prefson;
}
private String PRODUCT_ID(){
return getResources().getString(R.string.product_id);
}
public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
bp.handleActivityResult(requestCode, resultCode, intent);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
menu.clear();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
}
@Override
public void onDestroy() {
if (bp != null)
bp.release();
super.onDestroy();
}
private void showAD() {
if (mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
} else {
requestNewInterstitial();
}
}
private void requestNewInterstitial() {
AdRequest adRequest = new AdRequest.Builder()
.build();
mInterstitialAd.loadAd(adRequest);
}
private void shareTwitter() {
String message="Share Message";
Intent tweetIntent = new Intent(Intent.ACTION_SEND);
tweetIntent.putExtra(Intent.EXTRA_TEXT, message);
tweetIntent.setType("text/plain");
PackageManager packManager = Objects.requireNonNull(getActivity()).getPackageManager();
List<ResolveInfo> resolvedInfoList = packManager.queryIntentActivities(tweetIntent, PackageManager.MATCH_DEFAULT_ONLY);
boolean resolved = false;
for (ResolveInfo resolveInfo : resolvedInfoList) {
if (resolveInfo.activityInfo.packageName.startsWith("com.twitter.android")) {
tweetIntent.setClassName(
resolveInfo.activityInfo.packageName,
resolveInfo.activityInfo.name);
resolved = true;
break;
}
}
if (resolved) {
startActivity(tweetIntent);
} else {
Intent i = new Intent();
i.putExtra(Intent.EXTRA_TEXT, message);
i.setAction(Intent.ACTION_VIEW);
i.setData(Uri.parse("https://twitter.com/intent/tweet?text=" + urlEncode(message)));
startActivity(i);
Toast.makeText(getActivity(), "No Twitter app found!", Toast.LENGTH_LONG).show();
}
}
private String urlEncode(String s) {
try {
return URLEncoder.encode(s, "UTF-8");
} catch (UnsupportedEncodingException e) {
return "";
}
}
}
如有任何帮助,我们将不胜感激,谢谢!
最佳答案
您需要先从服务器读取该文件,然后解析结果...它可以像这个方法一样简单:
public String readFileFromServer(String fileUrl) {
String fileContent;
try {
URL url = new URL(fileUrl);
return new Scanner(url.openStream()).useDelimiter("\\A").next();
} catch (IOException e) {
throw new RuntimeException("Error while trying to read file from server!", e);
}
}
获取文件内容后,将其传递给parse()
方法即可。
关于java - MalformedJsonException : Use JsonReader. setLenient(true) 接受格式错误的 JSON - Android Studio,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57013054/
我在优化 JOIN 以使用复合索引时遇到问题。我的查询是: SELECT p1.id, p1.category_id, p1.tag_id, i.rating FROM products p1
我有一个简单的 SQL 查询,我正在尝试对其进行优化以删除“使用位置;使用临时;使用文件排序”。 这是表格: CREATE TABLE `special_offers` ( `so_id` int
我有一个具有以下结构的应用程序表 app_id VARCHAR(32) NOT NULL, dormant VARCHAR(6) NOT NULL, user_id INT(10) NOT NULL
此查询的正确索引是什么。 我尝试为此查询提供不同的索引组合,但它仍在使用临时文件、文件排序等。 总表数据 - 7,60,346 产品= '连衣裙' - 总行数 = 122 554 CREATE TAB
为什么额外的是“使用where;使用索引”而不是“使用索引”。 CREATE TABLE `pre_count` ( `count_id`
我有一个包含大量记录的数据库,当我使用以下 SQL 加载页面时,速度非常慢。 SELECT goal.title, max(updates.date_updated) as update_sort F
我想知道 Using index condition 和 Using where 之间的区别;使用索引。我认为这两种方法都使用索引来获取第一个结果记录集,并使用 WHERE 条件进行过滤。 Q1。有什
I am using TypeScript 5.2 version, I have following setup:我使用的是TypeScript 5.2版本,我有以下设置: { "
I am using TypeScript 5.2 version, I have following setup:我使用的是TypeScript 5.2版本,我有以下设置: { "
I am using TypeScript 5.2 version, I have following setup:我使用的是TypeScript 5.2版本,我有以下设置: { "
mysql Ver 14.14 Distrib 5.1.58,用于使用 readline 5.1 的 redhat-linux-gnu (x86_64) 我正在接手一个旧项目。我被要求加快速度。我通过
在过去 10 多年左右的时间里,我一直打开数据库 (mysql) 的连接并保持打开状态,直到应用程序关闭。所有查询都在连接上执行。 现在,当我在 Servicestack 网页上看到示例时,我总是看到
我使用 MySQL 为我的站点构建了一个自定义论坛。列表页面本质上是一个包含以下列的表格:主题、上次更新和# Replies。 数据库表有以下列: id name body date topic_id
在mysql中解释的额外字段中你可以得到: 使用索引 使用where;使用索引 两者有什么区别? 为了更好地解释我的问题,我将使用下表: CREATE TABLE `test` ( `id` bi
我经常看到人们在其Haxe代码中使用关键字using。它似乎在import语句之后。 例如,我发现这是一个代码片段: import haxe.macro.Context; import haxe.ma
这个问题在这里已经有了答案: "reduce" or "apply" using logical functions in Clojure (2 个答案) 关闭 8 年前。 “and”似乎是一个宏,
这个问题在这里已经有了答案: "reduce" or "apply" using logical functions in Clojure (2 个答案) 关闭 8 年前。 “and”似乎是一个宏,
我正在考虑在我的应用程序中使用注册表模式来存储指向某些应用程序窗口和 Pane 的弱指针。应用程序的一般结构如下所示。 该应用程序有一个 MainFrame 顶层窗口,其中有几个子 Pane 。可以有
奇怪的是:。似乎a是b或多或少被定义为id(A)==id(B)。用这种方式制造错误很容易:。有些名字出人意料地出现在Else块中。解决方法很简单,我们应该使用ext==‘.mp3’,但是如果ext表面
我遇到了一个我似乎无法解决的 MySQL 问题。为了能够快速执行用于报告目的的 GROUP BY 查询,我已经将几个表非规范化为以下内容(该表由其他表上的触发器维护,我已经同意了与此): DROP T
我是一名优秀的程序员,十分优秀!