我正在将一个项目转移到新的Android Native Development Kit(即JNI),我想抓住SIGSEGV,如果它发生(可能还有SIGILL,SIGABRT,SIGFPE),以便提供一个很好的崩溃报告对话框,而不是(或之前)当前发生的事情:该过程立即毫不客气地死亡,并且可能是操作系统重启它的一些尝试.(编辑: JVM/Dalvik VM捕获信号并记录堆栈跟踪和其他有用信息;我只是想为用户提供将该信息真正通过电子邮件发送给我的选项.)
情况是:我没有编写的大量C代码完成了这个应用程序中的大部分工作(所有游戏逻辑),虽然它在很多其他平台上都经过了很好的测试,但我完全有可能在我的Android中端口,将它提供垃圾并导致本机代码崩溃,所以我想要当前显示在Android日志中的崩溃转储(本机和Java)(我想在非Android情况下它将是stderr).我可以随意修改C和Java代码,尽管回调(进入和退出JNI)的数量大约为40,显然,小差异的奖励积分.
我听说过J2SE中的信号链接库,libjsig.so,如果我可以在Android上安全地安装这样的信号处理程序,这将解决我的问题的捕捉部分,但我看不到Android/Dalvik这样的库.
java-native-interface android signals segmentation-fault android-ndk
我有一个res/layout/main.xml
包括这些元素和其他:
<some.package.MyCustomView android:id="@+id/foo" (some other params) />
<TextView android:id="@+id/boring" (some other params) />
Run Code Online (Sandbox Code Playgroud)
在我的Activity的onCreate中,我这样做:
setContentView(R.layout.main);
TextView boring = (TextView) findViewById(R.id.boring);
// ...find other elements...
MyCustomView foo = (MyCustomView) findViewById(R.id.foo);
if (foo == null) { Log.d(TAG, "epic fail"); }
Run Code Online (Sandbox Code Playgroud)
其他元素成功找到,但foo
返回null.MyCustomView有一个构造函数,MyCustomView(Context c, AttributeSet a)
并且Log.d(...)
该构造函数的末尾在"史诗失败"之前的logcat中成功出现.
为什么是foo
null?
像以前的人一样,我在GridView项目之间有不必要的重叠:
请注意除最右边的列之外的每个列中的文本.
我与前一个问题的不同之处在于我不想要一个恒定的行高.我希望行高可以变化以适应每行中最高的内容,以有效利用屏幕空间.
查看GridView的源代码(不是权威副本,但kernel.org仍然是down),我们可以在fillDown()和makeRow()中看到最后一个View看到的是"引用视图":行的高度是从视图的高度,而不是最高的视图.这解释了为什么最右边的列没问题.不幸的是,GridView没有很好的设置让我通过继承来解决这个问题.所有相关领域和方法都是私人的.
所以,在我采取"克隆和拥有"这条破旧的臃肿路径之前,我在这里缺少一个技巧吗?我可以使用TableLayout,但这需要我自己实现numColumns="auto_fit"
(因为我想在电话屏幕上只需要一个长列),它也不会是一个AdapterView,这应该是它应该是.
编辑:事实上,克隆和自己在这里不实用.GridView依赖于其父类和兄弟类的不可访问部分,并导致至少导入6000行代码(AbsListView,AdapterView等)
我已阅读各种常见问题解答,这些常见问题解答git
没有明确跟踪重命名/移动,更喜欢寻找相同(或在某些情况下类似的?)文件.这很好,但它会处理这种情况:朋友的远程存储库有一个新功能(i18n)涉及一些新文件debian/po/*.po
.我有自己的这个项目的分支,并希望合并这个功能,但只是把文件po/*.po
(我可以做两个提交,或任何必要的).我希望远程仓库将继续接收该功能的更新,我想合并/樱桃选择这些提交并将它们应用于我新位置的文件.可以git
做到这一点,或许有某种映射"这些文件现在已经移到这里"?或者它是否比它的价值更痛苦,我应该接受debian
我的回购中略微奇怪的路径?
在写这个问题时解决了,但发布以防万一:
我正在设置这样的多个警报,具有不同的值id
:
AlarmManager alarms = (AlarmManager)context.getSystemService(
Context.ALARM_SERVICE);
Intent i = new Intent(MyReceiver.ACTION_ALARM); // "com.example.ALARM"
i.putExtra(MyReceiver.EXTRA_ID, id); // "com.example.ID", 2
PendingIntent p = PendingIntent.getBroadcast(context, 0, i, 0);
alarms.setRepeating(AlarmManager.RTC_WAKEUP, nextMillis, 300000, p); // 5 mins
Run Code Online (Sandbox Code Playgroud)
......并像这样接收它们:
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_ALARM)) {
// It's time to sound/show an alarm
final long id = intent.getLongExtra(EXTRA_ID, -1);
Run Code Online (Sandbox Code Playgroud)
警报在适当的时间传递给我的接收器,但通常EXTRA_ID
设置为错误的值:它是我在某个时刻使用的值,而不是我想要在那个特定时间传递的值.
虽然我的编程Android应用我只是不停地在插入元素的strings.xml没有为了任何.是否有按字母顺序对字符串元素进行排序的快捷键(如Ctrl+ Shift+ F可以组织android:
XML布局文件中的属性)?
我有一个应用程序,主要是用C编写的本机代码:Simon Tatham的谜题.当我遇到崩溃(使用信号处理程序)时,Java回溯只会告诉我问题的模糊区域:
W System.err: at name.boyle.chris.sgtpuzzles.SGTPuzzles.resizeEvent(Native Method)
W System.err: at name.boyle.chris.sgtpuzzles.SGTPuzzles$1.handleMessage(SGTPuzzles.java:126)
W System.err: at android.os.Handler.dispatchMessage(Handler.java:99)
Run Code Online (Sandbox Code Playgroud)
为了有任何诊断希望,我需要的是Android框架写入日志的本机回溯:
I DEBUG : #02 pc 0003e8ae /data/data/name.boyle.chris.sgtpuzzles/lib/libpuzzles.so
I DEBUG : #03 pc 0003ed62 /data/data/name.boyle.chris.sgtpuzzles/lib/libpuzzles.so
I DEBUG : #04 pc 00059060 /data/data/name.boyle.chris.sgtpuzzles/lib/libpuzzles.so
Run Code Online (Sandbox Code Playgroud)
据我所知,Android Market的崩溃报告不包括原生痕迹......是吗?
因此,我目前有我自己的崩溃捕手和记者,在上一个问题中描述,它将提供你带入登录的电子邮件撰写窗口.这很有效,有一个问题:用户不会阅读(或不相信)包描述中的解释,并且会被权限请求吓跑.
这些评论并不是让我感到烦恼,而是那些在没有安装的情况下逃跑的未知人数.:-(
那么如何在不使游戏需要一个可怕的日志权限的情况下获得崩溃的原生回溯呢?可能的方案包括:
backtrace()
.编辑:这里的大多数东西似乎都是必需的:http://github.com/android/platform_system_core/tree/master/debuggerd - 在项目中包含足够的东西会对ABI造成过度,臃肿,困难,不支持和脆弱修改/添加.似乎没有好好利用时间.我有一个使用ActionBar的应用程序,我自己处理方向更改:
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
Run Code Online (Sandbox Code Playgroud)
...并且菜单应该适合ActionBar而不会在横向上溢出,但不能在纵向中溢出:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="@string/Game" android:id="@+id/game" android:icon="@android:drawable/ic_menu_manage" android:showAsAction="ifRoom|withText"/>
<item android:title="@string/Type" android:id="@+id/type" android:icon="@android:drawable/ic_menu_edit" android:showAsAction="ifRoom|withText"/>
<item android:title="@string/Other" android:id="@+id/other" android:icon="@android:drawable/ic_menu_gallery" android:showAsAction="ifRoom|withText"/>
<item android:title="@string/Solve" android:id="@+id/solve" android:icon="@android:drawable/ic_menu_directions" android:showAsAction="ifRoom|withText"/>
<item android:title="@string/Help" android:id="@+id/help" android:icon="@android:drawable/ic_menu_help" android:showAsAction="ifRoom"/>
</menu>
Run Code Online (Sandbox Code Playgroud)
在启动时,这可以正常工作:
景观:
肖像:
(是的,我可以强制所有项目始终显示并且它们适合,如下所示,但可能会在较小的平板电脑上打破)
当模拟器更改方向时,ActionBar的容量似乎没有变化:
肖像,当我开始在风景中:
(这没关系,但不一致)
风景,当我开始画像时:
这看起来很傻,这也是我想解决这个问题的原因.
我将此调用添加到invalidateOptionsMenu(),但它没有帮助:
@Override
public void onConfigurationChanged(Configuration newConfig)
{
maybeMoveSomeViewsAround(newConfig);
super.onConfigurationChanged(newConfig);
invalidateOptionsMenu();
}
Run Code Online (Sandbox Code Playgroud)
(实际上我通过反射来调用它以实现向后兼容性,但调试器告诉我它确实被调用并且没有遇到异常.)
invalidateOptionsMenu()实际上最终在返回之前调用onCreateOptionsMenu()(它重新膨胀菜单),我可以在后面看到getResources().getConfiguration().orientation已经改变了.所以这真的令人费解.如果正在重新创建选项菜单,当方向已更改时,它必须是ActionBar本身缓存宽度?
有没有办法在不破坏/创建活动的情况下重新创建ActionBar?(因为后者在我的情况下有点贵)
编辑:这是一个显示问题的最小示例项目.
编辑2:我曾想过检查屏幕宽度并以编程方式调整始终和从不适当之间的showAsAction标志,但这需要知道(或猜测)每个项目的宽度.ActionBar的公共API在这一点上对我没有帮助.
我正在尝试遵循一个教程,假设如何添加一个浮动按钮,在教程中它说要将属性添加android:elevation
到按钮xml,如下所示:
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:id="@+id/editButton"
android:layout_gravity="center|right"
android:clickable="false"
android:background="@drawable/edit_grey"
android:layout_marginRight="1dp"
android:elevation="@dimen/elevation_low"/>
Run Code Online (Sandbox Code Playgroud)
但它不认识那个属性......我相信它与我的项目目标或sdk有关...有人可以帮助我吗?
这是一个测试文件.
将窗口大小调整到足以容纳所有四个盒子.请注意,容器并不像预期的那样宽.
将窗口大小调整到足够小,以使框在多行上.请注意,容器是页面的整个宽度(这是无意的).
为什么?是否有可能以不依赖于盒子大小的方式防止这种情况发生?
(见Firefox 3.5和Chrome 4.0.221.8.如果解决方案在IE6中不起作用,那很好.)
我正在尝试自动禁用动画,如本文所述,但这似乎只适用于命令行调用connectedAndroidTest
.我想在Studio中使用图形测试运行器,列表框显示通过/失败的测试.对于该adb shell pm grant ... android.permission.SET_ANIMATION_SCALE
运行器,权限grant()永远不会运行,似乎因为gradle任务installDebugAndroidTest
永远不会运行,而是运行器正在运行Gradle assembleDebugAndroidTest
(或者我在运行配置中指定的任何备用gradle任务),然后com.mypackage.test
由某些人安装在运行测试之前的其他(非Gradle?)方法.因此,该安装会重置任何先前的权限授予.
如何SET_ANIMATION_SCALE
在图形测试运行器的测试包安装和测试运行之间进行授权?
我正在尝试在与文档中的示例非常相似的场景中使用标签的关联代理。这是我的架构的一个子集(它是一个博客),使用声明式:
class Tag(Base):
__tablename__ = 'tags'
id = Column(Integer, primary_key=True)
tag = Column(Unicode(255), unique=True, nullable=False)
class EntryTag(Base):
__tablename__ = 'entrytags'
entry_id = Column(Integer, ForeignKey('entries.id'), key='entry', primary_key=True)
tag_id = Column(Integer, ForeignKey('tags.id'), key='tag', primary_key=True)
class Entry(Base):
__tablename__ = 'entries'
id = Column(Integer, primary_key=True)
subject = Column(Unicode(255), nullable=False)
# some other fields here
_tags = relation('Tag', backref='entries', secondary=EntryTag.__table__)
tags = association_proxy('_tags','tag')
Run Code Online (Sandbox Code Playgroud)
这是我尝试使用它的方法:
>>> e = db.query(Entry).first()
>>> e.tags
[u'foo']
>>> e.tags = [u'foo', u'bar'] # really this is from a comma-separated input …
Run Code Online (Sandbox Code Playgroud) 看起来android.database.Cursor.getColumnIndex(String)
在行循环上应该是不变的。
但我看到大量代码在执行以下操作:
try (Cursor cursor = database.query(...)) {
while (cursor.moveToNext()) {
String aString = cursor.getString(cursor.getColumnIndex(aColumnName));
// ... other loop code and more repeated use of getColumnIndex()
}
}
Run Code Online (Sandbox Code Playgroud)
这看起来很愚蠢而且浪费,除非 的结果getColumnIndex()
确实会随着对cursor.moveToNext()
-- 的调用而变化,并且这个调用应该被提升到循环之外,如下所示:
try (Cursor cursor = database.query(...)) {
int aStringIdx = cursor.getColumnIndex(aColumnName);
while (cursor.moveToNext()) {
String aString = cursor.getString(aStringIdx);
// ... other loop code
}
}
Run Code Online (Sandbox Code Playgroud)
或者在最坏的情况下(假设getColumnIndex()
要求您位于有效的数据行上):
try (Cursor cursor = database.query(...)) {
if (cursor.moveToFirst()) {
int aStringIdx = cursor.getColumnIndex(aColumnName);
do {
String …
Run Code Online (Sandbox Code Playgroud) android ×10
android-ndk ×2
adt ×1
alarms ×1
android-menu ×1
android-xml ×1
crash-dumps ×1
css ×1
css-float ×1
declarative ×1
eclipse ×1
extras ×1
git ×1
layout ×1
merge ×1
orm ×1
permissions ×1
python ×1
rename ×1
signals ×1
sqlalchemy ×1
sqlite ×1
stack-trace ×1
tags ×1
unit-testing ×1
width ×1
xml ×1
xml-editor ×1