小编Tho*_*alc的帖子

KitKat上的按钮文本消失(API级别19)

我的应用程序(游戏)的主菜单使用标准的Android按钮.它在我的所有设备上运行良好,除了使用Android 4.4.2的Nexus 7.问题如下:

在以下任何一种情况下,按钮的文本突然消失:

  • 按下按钮(当我触摸它时会立即发生,不需要释放它),
  • setEnabled(boolean) 在按钮上调用

例如,如果我按下"加载游戏",则在按下事件期间按钮会正确突出显示,但"加载游戏"会完全消失(该按钮具有空文本).

如果我删除所有自定义样式和行为,并仅使用默认字体等默认Android按钮,则问题仍然存在.

如果我将targetSdkVersion减少到18(从19),即使在Nexus 7上一切正常.

知道KitKat在这方面有什么变化吗?我没有发现任何可疑的东西.

我的revalant XML代码:

<TableLayout
    android:id="@+id/layoutGameMainmenu"
    android:layout_width="wrap_content"
    android:layout_height="83dip"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:orientation="vertical"
    android:gravity="center_vertical"
    android:visibility="gone" >

    <TableRow>

        <Button
            android:id="@+id/buttonLoadGame"
            android:layout_width="174dip"
            android:layout_height="40dip"
            android:layout_marginBottom="2dip"
            android:layout_marginRight="30dip"
            android:background="@drawable/button_gamemainmenu"
            android:text="buttonLoadGame"
            android:textColor="@color/button_gamemainmenu_text"
            android:textScaleX="0.9"
            android:textSize="16dp" />

        <Button
            android:id="@+id/buttonSettings"
            android:layout_width="174dip"
            android:layout_height="40dip"
            android:layout_marginBottom="2dip"
            android:layout_marginLeft="30dip"
            android:background="@drawable/button_gamemainmenu"
            android:text="buttonSettings"
            android:textColor="@color/button_gamemainmenu_text"
            android:textScaleX="0.9"
            android:textSize="16dp" />
    </TableRow>

    <TableRow>

        <Button
            android:id="@+id/buttonStartGame"
            android:layout_width="174dip"
            android:layout_height="40dip"
            android:layout_marginBottom="1dip"
            android:layout_marginRight="30dip"
            android:background="@drawable/button_gamemainmenu"
            android:text="buttonStartGame"
            android:textColor="@color/button_gamemainmenu_text"
            android:textScaleX="0.9"
            android:textSize="16dp" />

        <Button
            android:id="@+id/buttonQuit"
            android:layout_width="174dip"
            android:layout_height="40dip"
            android:layout_marginBottom="1dip"
            android:layout_marginLeft="30dip"
            android:background="@drawable/button_gamemainmenu"
            android:text="buttonQuit"
            android:textColor="@color/button_gamemainmenu_text"
            android:textScaleX="0.9"
            android:textSize="16dp" />
    </TableRow>
</TableLayout>
Run Code Online (Sandbox Code Playgroud)

关于上述代码的重要说明: …

java android button android-4.4-kitkat

9
推荐指数
1
解决办法
1667
查看次数

Dalvik中"短"字段所需的内存?

Java虚拟机也可以intshort字段使用-sized width (这取决于它们的内部实现).只有数组(short[])是例外,它总是保证它们占用的空间比int[]内部空间少.Dalvik怎么样?

例如,我有一个包含50个字段的类short.有时在我的应用程序中,存在10000个这样的类.这意味着short字段应该使用1MB的内存,但如果 Dalvik在short内部使用4个字节的值,那么这将是2MB的内存使用量.

我应该期待Dalvik使用多少内存?(这是指它的内部内存使用,我知道它可能不会被系统内存使用所反映,例如因为Dalvik已经从系统中预留了更多的内存.)

java android dalvik

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

使用超时多次调用CountDownLatch.await(int)

我使用CountDownLatch来等待来自另一个组件的某个事件(在不同的线程中运行).以下方法适合我的软件的语义,但我不确定它是否像我期望的那样工作:

mCountDownLatch.await(3000, TimeUnit.MILLISECONDS)
otherComponent.aStaticVolatileVariable = true;
mCountDownLatch.await(3500, TimeUnit.MILLISECONDS);
... <proceed with other stuff>
Run Code Online (Sandbox Code Playgroud)

方案应该如下:我等待3秒钟,如果锁存器没有倒计数到0,我用该变量通知另一个组件,然后我等待最多3.5秒.如果再次出现超时,那么我不在乎并将继续进行其他操作.

注意:我知道它看起来不像那样,但上面的场景在我的软件中是完全合理且有效的.

我确实阅读了await(int,TimeUnit)和CountDownLatch的文档,但我不是Java/Android专家,所以我需要确认.对我来说,所有场景看起来都有效:

  • 如果第一次等待成功,则另一次等待将立即返回
  • 如果第一个等待超时,则另一个等待仍然有效; 因此,如果另一个线程注意到静态信号,则第二个await可能会成功返回
  • 两个都等待调用超时(根据我的软件的语义,这很好)

我正确使用等待(...)吗?即使先前await(...)在同一个对象上超时,也能以上述方式使用第二个等待(...)吗?

java android synchronization countdownlatch

6
推荐指数
1
解决办法
2904
查看次数

多线程访问和线程的可变缓存

如果我读完一篇关于多线程的完整章节/书,我就能找到答案,但我想要一个更快的答案.(我知道这个 stackoverflow问题类似,但还不够.)

假设有这个类:

public class TestClass {
   private int someValue;

   public int getSomeValue() { return someValue; }
   public void setSomeValue(int value) {  someValue = value; }
}
Run Code Online (Sandbox Code Playgroud)

有两个线程(A和B)访问此类的实例.请考虑以下顺序:

  1. 答:getSomeValue()
  2. B:setSomeValue()
  3. 答:getSomeValue()

如果我是对的,someValue必须是volatile,否则第3步可能不会返回最新值(因为A可能有缓存值).它是否正确?

第二种情况:

  1. B:setSomeValue()
  2. 答:getSomeValue()

在这种情况下,A将始终获得正确的值,因为这是它的第一次访问,因此他还没有缓存值.这是正确的吗?

如果以第二种方式访问类,则不需要volatile/synchronization,或者是它?

请注意,此示例已简化,实际上我想知道复杂类中的特定成员变量和方法,而不是整个类(即哪些变量应该是volatile或具有同步访问权限).重点是:如果更多线程访问某些数据,是否需要通过所有方式进行同步访问,还是取决于它们访问它的方式(例如顺序)?


阅读评论后,我尝试用另一个例子来说明我的困惑的来源:

  1. 从UI线程: threadA.start()
  2. threadA调用getSomeValue(),并通知UI线程
  3. UI线程获取消息(在其消息队列中),因此它调用: threadB.start()
  4. threadB调用setSomeValue(),并通知UI线程
  5. UI线程获取消息,并通知threadA(以某种方式,例如消息队列)
  6. threadA调用 getSomeValue()

这是一个完全同步的结构,但为什么这意味着threadA将在步骤6中获得最新的值?(如果someValue不是易失性的,或者从任何地方访问时都不会放入监视器)

java multithreading android volatile

6
推荐指数
1
解决办法
2490
查看次数

XML与setImageDrawable/setImageBitmap

如果我预加载某些图像,在我的应用程序中是有利的.我这样做是正确的,在的AsyncTask,因为它是书面的正式文档.但是我有一个关于何时应该设置的问题/疑问.

我将展示代码片段.需要注意的是它简化了(他们的互操作性是我真正的代码更好,它会检查空值,等等).

让我们先看看原始(非预装)版本:

<ImageView
    android:id="@+id/imageViewMyGraphicalImageElement"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="centerCrop" 
    android:src="@drawable/my_graphical_element" >
</ImageView>
Run Code Online (Sandbox Code Playgroud)

预加载版本具有以下XML(请注意缺少src属性):

<ImageView
    android:id="@+id/imageViewMyGraphicalImageElement"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="centerCrop">
</ImageView>
Run Code Online (Sandbox Code Playgroud)

以及预装代码的片段:

sBitmap = bitmapBitmapFactory.decodeResource(context.getResources(), R.drawable.my_graphical_element, options); 
// 'sBitmap' is a Bitmap reference, while 'options' is BitmapFactory.Options
Run Code Online (Sandbox Code Playgroud)

最后,我设置它的地方:

setContentView(R.layout.main);
...
ImageView imageViewMyGraphicalImageElement= (ImageView) findViewById(R.id.imageViewMyGraphicalImageElement);
imageViewMyGraphicalImageElement.setImageBitmap(sBitmap); 
Run Code Online (Sandbox Code Playgroud)

问题:显然,基于xml的解决方案调用setContentView(...)之前知道图像.预加载版本该调用之后设置图像.有什么区别吗?由于这个原因,是否可以跳过某些自动缩放或系统完成的其他事情?

java android drawable android-layout

5
推荐指数
1
解决办法
2699
查看次数

通知单个线程:notify,notifyAll或concurrent.locks.Condition?

有时我需要醒来或发送一个单独的线程,我想知道什么是最好和最有效的方法.

第一个解决方案是信号结合wait-notify(我知道如何正确实现这种模式,这不是问题).

我在某处读到了使用java.concurrent库和CountDownLatch信令的效率更高.我也检查了concurrent.locks.Condition,但是这个主题声明它只是一个(程序员方面的)更安全和通用的结构,与之相比没有性能优势notify/notifyAll.彼得Lawrey建议使用并发库,而不是notify-notifyAll这个意见,所以现在我感到困惑的是要使用的最佳实践.

一个相关的问题:哪个性能更好,notify或者notifyAll在我的情况下(即如果我有一个线程)?我知道有很多类似的线索,但没有一个给出明确的答案.在我的情况下,功能上,我使用哪个并不重要,但我想知道哪个更快.

java performance multithreading android

5
推荐指数
1
解决办法
608
查看次数

如果没有访问类,静态init是否保证不运行?

我知道有很多这方面的主题和资源,但我想知道一个非常具体的问题(可能需要很长时间才能检查所有来源以获得明确答案).

我知道JVM/Dalvik保证当你访问类的静态字段时(final static原始值除外),类的静态字段已经初始化.反之亦然吗?如果我从来没有在所有访问类(例如,因为switch-case在另一个静态方法的代码永远不会达到一定的分支),是它保证了虚拟机并没有初始化这个类的静态?

假设我有一个这样的类:

public class Boo {
      public static int[] anything = new int[] { 2,3,4 };
      private static int[] something = new int[] { 5,6,7 }; // this may be much bigger as well

      public static final int[] getAndClear() {
           int[] st = something;
           something = null;
           return st;
      }
}
Run Code Online (Sandbox Code Playgroud)

我的应用程序是一个非常特殊的应用程序(在某些方面不典型),并且它可能包含数百个类,例如Boo(由代码生成器生成),其中something可能是不同元素计数的数组(因此它可能包含很多元素,如好吧有时候).

根据应用程序输入,许多这些预生成的类可能永远不会被访问.我希望很多int[]对象被不必要地初始化,占用大量内存.

java android static-methods dalvik lazy-initialization

5
推荐指数
1
解决办法
164
查看次数

在非 UI 线程上实例化视图

我知道 UI 元素(视图层次结构)只能从 UI 线程进行操作。对于后台操作,可以使用 AsyncTask,它提供事件处理程序以到达 UI 线程。

简而言之,是否允许getApplicationContext()在非 UI 线程中实例化 View(绑定到)?这个自定义 View 后代 - 一旦实例化 - 从UI 线程添加到视图层次结构。所以只有构造函数调用是在Asynctask.doInBackground(); 中完成的。它将 ( addView(...))附加到 Activity 的根布局层次结构仍然在 UI 线程中完成。

详细说明:

public MyView extends View {
     public MyView(Context context) { 
            ...
     }
...
}
Run Code Online (Sandbox Code Playgroud)
  1. 我做了一个自定义视图,覆盖onDraw(...)等。

  2. 当用户在我的主 Activity 中单击某个 MenuItem 时,会创建另一个 Activity (MyOtherActivity) 并显示哪个屏幕正是 MyView

  3. 由于必须立即显示 MyOtherActivity 的屏幕,因此我在 AsyncTask 中预先实例化 MyView,而用户在主 Activity 中的其他位置(即他还没有单击该 MenuItem)。MyView 引用存储在静态数据成员中。

  4. MyOtherActivity.onCreate()被调用时,它的构造函数代码从静态中获取 MyView,并通过addView(...).

  5. (我知道静态变量可能会导致内存泄漏,因此我将其设置为null不需要时。)

MyView …

java android android-ui android-asynctask android-view

4
推荐指数
1
解决办法
1045
查看次数

方法中"太多"局部变量的性能影响?

我被分配了扩展软件的某个组件(由其他人编写).它是用Android编写的,完全用Java编写(没有我知道的本机/ c ++组件).

熟悉代码时,我遇到了一个方法(渲染类的绘图方法).该方法涉及一个更新对象的大循环(然后另一个方法将在以后呈现它们).该方法的创建者似乎在循环之前将所有/大多数成员变量和数组以及其他对象的字段缓存到局部变量中.代码看起来像这样:

    float[] coordArr = mCoordArr;
    float[] texCoordArr = mTexCoordArr;
    float[] cArray = mColArray;

    // ... there are further locals too, I didn't copy all here

    float[] color = mColor;
    float r = color[0];
    float g = color[1];
    float b = color[2];
    float a = color[3];

    int texw = mTexW;
    int texH = mTexH;
    Font font = mFont;
    float[] ccords = font.ccords;
    float cf = font.cf;
    float cu = font.cu;
    int len = mCurLength;

    // Update …
Run Code Online (Sandbox Code Playgroud)

java performance android local-variables dalvik

4
推荐指数
1
解决办法
983
查看次数

为什么字节码在直接访问字段时调用 Object-&gt;getClass()

我反编译了 Java(实际上是 Dalvik)字节码。在方法的开头,我直接访问实例成员的字段(即不通过 getter)。

似乎 Java 调用Object.getClass()了访问的实例成员 ( mOther),但没有在任何地方使用结果。这是某种检查吗?为什么需要这个电话?我怀疑这是因为我直接访问了一个字段(在该类中定义),但我没有看到连接。

Java代码和反编译后的字节码如下。

(请注意,最后一条指令lifeTime作为常量加载,0x0001因为 in MyOtherClass,我有lifeTime一个public final字段,并且当前是从代码初始化的。)

MyOtherClass other = mOther;
if (mAge >= other.lifeTime) { // lifeTime is initialized to 0x0001
   end();
   return;
}

.line 53
move-object/from16 v0, p0
iget-object v0, v0, Lcom/example/engine/MyClass1;->mOther:Lcom/example/engine/MyOtherClass;
move-object/from16 v16, v0

.line 54
.local v16, other:Lcom/example/engine/MyOtherClass;
move-object/from16 v0, p0

iget v0, v0, Lcom/example/engine/MyClass1;->mAge:I
move/from16 v18, v0

// Why is Object->getClass() called?
invoke-virtual/range {v16 .. v16}, …
Run Code Online (Sandbox Code Playgroud)

java android bytecode dalvik

3
推荐指数
1
解决办法
498
查看次数