小编mus*_*ikk的帖子

如何使用印尼语本地化Android应用程序

我需要将我的应用程序本地化为印度尼西亚语.我的应用程序的资源文件夹包含每种语言的"值"子文件夹列表,例如"values-fr"文件夹.

但我阅读有关Android开发人员文档的令人困惑的信息.

请注意,Java使用了几个不推荐使用的双字母代码.希伯来语("他")语言代码被重写为"iw",印度尼西亚语("id")被改写为"in",而意第绪语("yi")被改写为"ji".即使您构造自己的Locale对象,也不仅仅是针对各种查找方法返回的实例,这种重写也会发生.

怎么理解这个?基本上,我应该将我的文件夹命名为"values-in"或"values-id",以便在具有印尼语区域设备的设备上正确显示印尼语文本?

android localization

35
推荐指数
1
解决办法
1万
查看次数

Android AdMob内存使用情况

我很困惑AdMob SDK似乎使用了多少内存,以及这个内存实际位于何处.让我解释.

我的应用程序有两种风格:免费和付费.免费版有AdMob广告,否则代码几乎相同(常用的Android lib).

我在Nexus 4(Android 4.2.1)上运行应用程序并比较内存使用情况.我查看应用程序在设备设置>应用程序>运行中使用的系统内存.我还查看GC logcat消息报告的Dalvik堆内存,并使用HPROF文件.

当我运行付费版本时,我可以看到:

  • 系统内存:大约16MB
  • Dalvik堆大小:大约10MB

当我运行免费版时,我可以看到:

  • 系统内存:约29MB
  • Dalvik堆大小:大约11MB

换句话说,两个版本的dalvik堆大小相似.但实际使用的系统内存10MB +更高!

花了很多时间学习内存分析(http://www.youtube.com/watch?feature=player_embedded&v=_CruQY55HOk),花了几个小时查看HPROF文件以消除任何可能的泄漏,我只能看到一个结论:

AdMob使用的10MB额外系统内存实际上是本机内存,使用malloc分配,在dalvik堆之外!

现在我想知道两件事:

  1. 我相信,由于免费版系统内存比付费版大10MB,因此在内存压力的情况下更容易被操作系统杀死.或者Android操作系统是否只考虑了Dalvik堆来决定杀死哪个应用程序?
  2. 有没有办法调整AdMob SDK以选择允许分配多少内存?

非常感谢

memory android admob

21
推荐指数
2
解决办法
3641
查看次数

ColumnScope 修饰符作为可组合项的参数

我正在制作一个类似脚手架的可组合项,其中包含一个文本可组合项。我希望脚手架具有文本的修饰符参数。我希望能够从 ColumnScope 传递修饰符,例如能够对齐文本。

这是脚手架的简化版本:

@Composable
fun MyScaffold(
    text: String,
    modifier: Modifier,
) {
    Text(
        modifier = modifier,
        text = text
    )
}
Run Code Online (Sandbox Code Playgroud)

调用 Scaffold 时,我想传递一个修饰符,以便文本水平对齐:

@Preview
@Composable
fun PreviewScaffold() {
    MyScaffold(
        text = "Hello",
        modifier = Modifier.align(Alignment.CenterHorizontally)
    )
}
Run Code Online (Sandbox Code Playgroud)

然而,这不能编译,因为align()方法是ColumnScope中的扩展函数,因此它仅在ColumnsScope内有效。

如何将 ColumnScope Modifier 作为 MyScaffold 的参数传递?

请注意,另一种方法是在脚手架中传递整个文本可组合项,而不仅仅是一个字符串,但我宁愿只有一个字符串,这样我就可以在脚手架内制作大部分样式,但只需为外部调用者提供覆盖它的可能性。

谢谢!

android android-jetpack-compose

14
推荐指数
1
解决办法
6025
查看次数

如何调试Android ANR?

我的Android应用程序最近在Google Play控制台中收到了很多ANR报告.由于我在应用中包含Google Analytics时就开始发生这种情况,因此我强烈怀疑Google Analytics会导致这种情况发生.

问题是我知道如何使用堆栈跟踪来调试崩溃.但我不确定如何调试ANR.我猜ANR意味着主线程在某处被阻塞.但是如何知道它被阻止的位置?见下面我最近得到的典型ANR之一.如何解读它并开始弄清楚应用程序挂起的位置?

PS:由于使用了DexGuard代码混淆器,堆栈中的某些类/方法看起来很奇怪.

ANR报告:

DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0 hwl=0 hwll=0)
"main" prio=5 tid=1 VMWAIT
| group="main" sCount=1 dsCount=0 obj=0x40022198 self=0xcec8
| sysTid=5001 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=-1345006496
| schedstat=( 1265991222 1037628169 649 )
at dalvik.system.DexFile.openDexFile(Native Method)
at dalvik.system.DexFile.<init>(DexFile.java:103)
at dalvik.system.DexFile.loadDex(DexFile.java:142)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at o.?$?$?.<clinit>((null):-1)
at o.?$?.onServiceConnected(:-1)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1064)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1081)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(Native Method)

"Binder Thread …
Run Code Online (Sandbox Code Playgroud)

debugging stack android google-analytics crash-reports

12
推荐指数
1
解决办法
1万
查看次数

市场更新后自动重启应用程序

每当我在Market中发布我的应用程序的新版本时,如果用户启用了"自动更新"选项,该应用程序将自动更新.

该应用程序包含一个不断运行的服务.但是当自动更新发生时,旧的正在运行的应用程序被终止,但新的应用程序未启动.由于更新主要是透明地发生在用户身上,因此应该在更新后自动重新启动应用程序的服务,以便几乎不会中断服务.

使用市场上的真实更新对此进行测试有点困难,因此我使用以下两个adb命令来模拟此更新过程.安装第一版:

adb install oldversion.apk
Run Code Online (Sandbox Code Playgroud)

自动更新:

adb install -r newversion.apk
Run Code Online (Sandbox Code Playgroud)

运行第二个命令后,应用程序成功更新,但已停止但未重新启动.

我们如何让新版本的服务自动启动?

service android auto-update google-play

9
推荐指数
2
解决办法
5057
查看次数

Google Analytics的应用内价格格式

我的应用包含可以购买的应用内商品.我使用结算API来检索可以购买的产品列表及其价格.检索到的价格是包含货币和价格的格式化字符串,例如"$ 2.50".

现在我使用Google AnalyticsAPI来跟踪购买情况.为了发送价格,这个API需要一个很长的微观参数.所以我应该发送(2.50*1000000).

是否有API将第一个价格(从结算API中检索)转换为第二个价格(发送到Analytics API)?

当然我自己可以做一个简单的String解析转换,但如果我这样做,我会害怕意外的情况.例如,在某些区域设置中,价格将包含","而不是".".

编辑

一个自然的解决方案是使用NumberFormat从"$ 2.50"转换为2.50.

Double price = NumberFormat.getCurrencyInstance().parse(priceStr).doubleValue();
Run Code Online (Sandbox Code Playgroud)

但是,从Google Play检索的价格字符串格式显然位于手机所在国家/地区的区域设置中,但NumberFormat会使用手机的区域设置,但不一定相同...

android billing google-analytics in-app-purchase

8
推荐指数
1
解决办法
873
查看次数

Use NavHostFragment in Jetpack Compose

We have a legacy app that we start migrating to Jetpack Compose. The app has a single activity, uses Navigation component with a navigation XML graph to navigate between fragments.

We are following this approach:

  • Migrate each fragment one at a time
  • For each fragment make a @Composable screen that provides the same UI as the fragment
  • From the fragment onCreateView() set the content to the newly created screen

Now, say we had Fragment1 containing some action to navigate to …

android android-fragments android-architecture-navigation android-jetpack-compose

8
推荐指数
1
解决办法
5581
查看次数

杀死了Android服务和静态变量

使用Android 2.1+.我有一个服务,不时被操作系统杀死(由于内存压力,我猜).

此服务使用类的静态成员字段维护某些状态.我期望静态字段保持其值,尽管操作系统会杀死并重新启动服务.

但似乎不会发生这种情况.重新启动后,静态变量将重置为默认值.它应该发生什么?尽管杀死/重启,我应该使用另一种方式来保持持久状态吗?

service static android

7
推荐指数
1
解决办法
4097
查看次数

为什么ListView在ListPreference对话框中保持在TextView之上?

我需要创建一个自定义ListPreference对话框,以便我可以在List(ListView)上方添加一些标题文本(TextView).我创建了MyListPreference类,它扩展了ListPreference并覆盖了onCreateDialogView():

@Override
protected View onCreateDialogView() {
    LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v = (View) inflater.inflate(R.layout.dialog_preference_list, null);
    return v;
}
Run Code Online (Sandbox Code Playgroud)

我的XML布局dialog_preference_list.xml包含:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

    <ListView
        android:id="@android:id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawSelectorOnTop="false"
        android:scrollbarAlwaysDrawVerticalTrack="true" />

</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

问题:TextView显示在ListView下面而不是上面.我需要TextView在上面.我已尝试使用LinearLayout和RelativeLayout(使用"下方"或"上方"属性)但没有成功:我找不到将TextView放在ListView上方的方法...布局非常简单,我看不到为什么列表保持在上面...另外,请注意问题发生在真实设备(Nexus 4,Android 4.2.2)和模拟器上.但是,在查看Eclipse的图形布局中呈现的布局时,布局是正确的!查看附图.

关于如何解决这个问题的任何想法?

在设备上呈现的布局(不正确):

在设备上呈现的布局(不正确)

在Eclipse上呈现的布局(正确):

在Eclipse上呈现的布局(正确)

使用解决方案10.07.2013进行编辑

正如接受的答案所暗示的那样,问题来自在ListPreference的onPrepareDialogBu​​ilder()中使用builder.setSingleChoiceItems().我通过扩展ListPreference并覆盖onCreateDialogView()来修复它,以构建没有构建器的Dialog,这样我就可以创建一个自定义视图,显示列表项上方的标题文本.

GPListPreference.java:

public class GPListPreference extends ListPreference {
    ...

    @Override
    protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
        builder.setNegativeButton(null, null);
        builder.setPositiveButton(null, null);
    }

    private int getValueIndex() {
        return findIndexOfValue(getValue());
    }

    @Override …
Run Code Online (Sandbox Code Playgroud)

android listpreference android-listview

7
推荐指数
1
解决办法
1665
查看次数

jetpack compose 是否使用drawable-night 文件夹?

我们有一个基于视图的 Android 应用程序,文件夹中包含一些可绘制的内容,文件夹res/drawable中包含夜间模式的对应内容res/drawable-night

当使用旧视图时,从 XML 布局文件引用可绘制对象时R.drawable.foo,系统会根据我们处于白天还是夜间模式从一个res/drawable或多个文件夹中选择可绘制对象。res/drawable-night

使用 jetpack compose 时,我们在 Image 可组合项中引用可绘制项,如下所示:

Image(painter = painterResource(R.drawable.foo))
Run Code Online (Sandbox Code Playgroud)

但是,这总是从文件夹中选择可绘制对象res/drawable,忽略日/夜模式。

我们可以这样做来选择正确的可绘制对象,但我们需要isSystemInDarkTheme()在所有使用可绘制对象的可组合项中测试夜间模式 ( ),具体取决于夜间模式:

Image(painter = painterResource(id = if (isSystemInDarkTheme()) R.drawable.foo_dark else R.drawable.foo_light))
    
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以确保像在传统视图系统中一样,正确且透明地选择白天或夜间模式下的可绘制对象?

android android-jetpack android-jetpack-compose

7
推荐指数
2
解决办法
1914
查看次数