小编Tim*_*mmm的帖子

以编程方式在LinearLayout中设置边距

我正在尝试使用Java(而不是XML)创建一个LinearLayout,其中的按钮可以填充屏幕并具有边距.这是没有边距的代码:

LinearLayout buttonsView = new LinearLayout(this);
buttonsView.setOrientation(LinearLayout.VERTICAL);
for (int r = 0; r < 6; ++r) {
    Button btn = new Button(this);
    btn.setText("A");

    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); // Verbose!
    lp.weight = 1.0f; // This is critical. Doesn't work without it.
    buttonsView.addView(btn, lp);
}

ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
setContentView(buttonsView, lp);
Run Code Online (Sandbox Code Playgroud)

这样工作正常,但你怎么给按钮边距,所以它们之间有空间?我尝试过使用LinearLayout.MarginLayoutParams,但是没有weight成员,所以没有用.如果你lp在它的构造函数中传递它也不起作用.

这不可能吗?因为它确实看起来,并且它不会是第一个Android布局任务,你只能用XML做.

java layout android margin view

260
推荐指数
8
解决办法
33万
查看次数

进一步了解setRetainInstance(true)

什么究竟,当你调用发生setRetainInstance(true)Fragment?文档几乎不存在,这似乎是一个非常重要的功能.具体来说,我想知道这个序列(我编造的)有多少是真的:

  1. 用户旋转设备.
  2. 该片段从分离ActivityFragment.onDetach()被调用.
  3. 活动被摧毁; Activity.onDestroy()叫做.
  4. 所述Activityjava对象被删除(如果可能,通过GC).
  5. Activity创建一个新的java对象; 它的构造函数,并被onCreate()调用.
  6. Activity.onCreate()我们要么setContentView(...)设置包含片段的布局,要么我们FragmentTransaction 用来添加片段.
  7. 我真的不确定这一点,但我认为android很聪明,可以找到旧的片段,并呼吁Fragment.onAttach()将它重新连接到新的Activity
  8. Activity.onResume()调用下一个(或之前?谁知道?).

那是对的吗?即使我FragmentTransaction.add(new MyFragment(), ...)第一次明确使用,Android是否足够智能找到旧片段?如果是这样,我如何避免添加另一个片段onCreate()?我需要做这样的事吗?:

    if (getSupportFragmentManager().findFragmentByTag("foo") == null)
    {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.add(new FooFragment(), "foo").commit();
    }
Run Code Online (Sandbox Code Playgroud)

android rotation android-fragments android-activity

103
推荐指数
2
解决办法
5万
查看次数

为什么django的prefetch_related()只能用于all()而不能用于filter()?

假设我有这个模型:

class PhotoAlbum(models.Model):
    title = models.CharField(max_length=128)
    author = models.CharField(max_length=128)

class Photo(models.Model):
    album = models.ForeignKey('PhotoAlbum')
    format = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)

现在,如果我想有效地查看相册子集中的一部分照片.我这样做:

someAlbums = PhotoAlbum.objects.filter(author="Davey Jones").prefetch_related("photo_set")
for a in someAlbums:
    somePhotos = a.photo_set.all()
Run Code Online (Sandbox Code Playgroud)

这只做了两个查询,这是我所期望的(一个是获得专辑,然后是一个像`SELECT*IN photos WHERE photoalbum_id IN().

一切都很棒.

但如果我这样做:

someAlbums = PhotoAlbum.objects.filter(author="Davey Jones").prefetch_related("photo_set")
for a in someAlbums:
    somePhotos = a.photo_set.filter(format=1)
Run Code Online (Sandbox Code Playgroud)

然后它做了大量的查询WHERE format = 1!我做错了什么或django不够聪明,意识到它已经取出所有的照片并可以在python中过滤它们?我发誓我在文档中的某个地方读到它本应该这样做......

django orm filter prefetch

81
推荐指数
2
解决办法
6万
查看次数

Rust中的惯用回调

在C/C++中,我通常使用普通函数指针进行回调,也可以传递一个void* userdata参数.像这样的东西:

typedef void (*Callback)();

class Processor
{
public:
    void setCallback(Callback c)
    {
        mCallback = c;
    }

    void processEvents()
    {
        for (...)
        {
            ...
            mCallback();
        }
    }
private:
    Callback mCallback;
};
Run Code Online (Sandbox Code Playgroud)

在Rust中这样做的惯用方法是什么?具体来说,我的setCallback()功能应该mCallback采用什么类型,应该是什么类型?它需要Fn吗?也许FnMut?我保存Boxed吗?一个例子是惊人的.

callback rust

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

禁用Visual Studio代码中的窥视

有没有办法在Visual Studio代码中禁用ctrl-click'peek'功能?理想情况下,我想按住Ctrl键单击以在新选项卡中打开包含定义的文件.

编辑:我提交了一个问题,至少让它不那么混乱.显然我的术语有些错误.

澄清一下,有两个动作:

  1. 右键单击 - > Peek Definition
  2. 右键单击 - > 转到"定义"(绑定到按住Ctrl键单击)

他们的行为如下:

  1. PD,单一定义
    • 打开显示定义的内联界面.
  2. PD,多种定义

    • 打开显示定义的内联界面.
  3. GtD,单一定义

    • 打开包含定义的文件.
  4. GtD,多种定义
    • 随机选择一个定义,打开该文件,以及显示所有定义的内联界面.

所有这些都很好,除了最后一个.做这两件事会导致真正多余且令人困惑的UI,如下所示:

混乱!

应该有办法让这些行为之一:

  • 随机选择一个定义,打开该文件.

要么:

  • 打开内联界面显示所有定义(在当前文件中)

visual-studio-code

68
推荐指数
1
解决办法
4354
查看次数

使用OAuth2为app*和*网站进行身份验证

我正在开发一个主要通过应用程序访问的网站,我想使用OAuth2进行用户注册和身份验证.由于它是Android应用程序,我将开始使用Google的OAuth2内容,因为它在Android上提供了不错的用户界面.

Google表示,"您可以选择使用Google的身份验证系统作为外包用户身份验证的方式.这可以消除创建,维护和保护用户名和密码存储的需要." 这就是我想要做的.然而,当我浏览他们的所有示例和诸如此类的东西时,我只能找到有关网站应用程序根据Google服务对用户进行身份验证的内容.

事实上,当我使用Google的OAuth2注册我的应用程序("客户端")时,网站客户端和"已安装"客户端(即移动应用程序)可以选择,但不能同时选择两者.我可以创建两个单独的客户端,但我读了OAuth2草案,我认为会有一个问题,我现在将解释.

以下是我设想的工作方式:

OAuth2流程图

  1. 用户要求MyApp访问他的私人数据.
  2. 应用程序使用Android的AccountManager类为Google的API请求访问令牌.
  3. Android向用户说"应用'MyApp'希望在Google上访问您的基本信息.这可以吗?"
  4. 用户说是的.
  5. AccountManager 使用手机上存储的凭据连接到Google的OAuth2服务器,并要求提供访问令牌.
  6. 返回访问令牌(在绿线后面).
  7. AccountManager 将访问令牌返回给MyApp.
  8. MyApp向MySite发送请求以获取用户的私有数据,包括访问令牌.
  9. MySite需要使用访问令牌验证用户.它验证了此处描述的令牌,谷歌 - "谷歌,这个令牌有效吗?".
  10. 现在,我想要发生的事情是谷歌说"是的,无论是谁给你的确是那个用户."但我认为实际发生的事情(基于OAuth2草案和Google的文档)是它会说"不"方式!该令牌仅对MyApp有效,而且你是MySite.GTFO!".

那我该怎么做呢?请不要说"使用OpenID"或"不要使用OAuth2"或其他类似无益的答案.哦,我真的想用漂亮的,以保持AccountManager用户界面,而不是糟糕的弹出WebView小号

编辑

来自Nikolay的临时答案(我会报告它是否有效!)它实际上应该有效,而Google的服务器并不关心访问令牌的来源.对我来说似乎有点不安全,但我会看看它是否有效!

更新

我用Facebook而不是Google实现了这种模式,它完全有效.OAuth2服务器不关心访问令牌的来源.至少Facebook没有,所以我认为谷歌也没有.

鉴于此,存储访问令牌是一个非常糟糕的主意!但是我们也不想让Facebook/Google的服务器检查每个请求的身份验证,因为它会减慢一切.可能最好的办法是为您的站点添加一个额外的身份验证cookie,当您的访问令牌被验证时,您可以将其分发,但更简单的方法就是将访问令牌视为密码并存储其哈希值.你不需要加盐它,因为访问令牌真的很长.所以上面的步骤变成了:

9. MySite需要使用访问令牌验证用户.首先,它检查哈希有效访问令牌的缓存.如果在那里找到令牌的散列,则它知道用户已经过身份验证.否则,它会按照此处所述与Google进行核对- Google,"此令牌是否有效?".

10.如果Google说访问令牌无效,我们会告诉用户GTFO.否则谷歌说"是的,这是一个有效的用户",然后我们检查我们的注册用户数据库.如果找不到Google用户名(或Facebook id,如果使用Facebook),我们可以创建新用户.然后我们缓存访问令牌的散列值.

android oauth google-authentication oauth-2.0

63
推荐指数
2
解决办法
2万
查看次数

编写向后兼容的Android代码

我正在编写一个应用程序,该应用程序使用仅在最新API级别提供的某些功能和类 - 16,但我希望它在API级别为15的设备上运行时没有错误.

让我们举几个例子.一个新类:Android.widget.Advanceable和一个新的/重命名的方法View.setBackground()::

我可以这样做:

Advanceable myAdvanceable = ...;

if (android.os.Build.VERSION.SDK_INT >= 16)
{
    myView.setBackground(...);
    myAdvanceable.advance();
}
else
{
    myView.setBackgroundDrawable(...); // The old function name.
    // Don't bother advancing advanceables.
}
Run Code Online (Sandbox Code Playgroud)

如果我将minSdk设置为15但构建目标为16(即在Project Properties-> Android中),它实际上将编译而没有错误.至少在某些时候.Eclipse对于错误有点随机,并且有时会说"setBackground()仅在API级别> = 16"或类似的情况下可用,但如果我只是清理项目那些错误就会神奇地消失.

所以我的问题是,我被允许这样做吗?如果我在API级别15设备上运行代码,代码是否会崩溃?如果真的到达16代码,它会崩溃吗?Eclipse为什么不阻止我构建它?

编辑1

谢谢你的答案,我想问题应该是:为什么lint不会警告我使用新的API?

我在我的清单中有这个,并且我正在使用API​​级别16的功能,但它仍然没有警告我:

<uses-sdk android:minSdkVersion="15"
    android:targetSdkVersion="16"/>
Run Code Online (Sandbox Code Playgroud)

此外,我仍然不确定整个类何时是API级别的新手,例如Advanceable.具体来说,如果我将它们用作成员变量.

编辑2

答案结果证明是"Eclipse是错误的地狱",但Nico的回答也非常有帮助.

api compatibility android

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

ScrollView中的MapFragment

我有一个新的MapFragments ScrollView.实际上它是一个SupportMapFragment,但无论如何.它有效,但有两个问题:

  1. 滚动时,会留下黑色面具.黑色完全覆盖了地图所在的区域,除了+/-缩放按钮所在的孔.见下面的截图.这是在Android 4.0上.

  2. requestDisallowInterceptTouchEvent()当用户与地图交互以防止ScrollView拦截触摸时,视图不会使用,因此如果您尝试在地图中垂直平移,则只会滚动包含ScrollView.理论上我可以派生一个视图类MapView并添加该功能,但是如何才能MapFragment使用我的自定义MapView而不是标准的?

滚动问题的部分截图

android google-maps android-mapview google-play-services

53
推荐指数
4
解决办法
2万
查看次数

如何提供 memcpy 的实现

我正在尝试编写一些带有memset-style 循环的裸机代码:

for (int i = 0; i < N; ++i) {
  arr[i] = 0;
}
Run Code Online (Sandbox Code Playgroud)

它是用 GCC 编译的,GCC 足够聪明,可以将其转换为对memset(). 不幸的是,因为它是裸机,我没有memset()(通常在 libc 中)所以我收到链接错误。

 undefined reference to `memset'
Run Code Online (Sandbox Code Playgroud)

似乎进行这种转换的优化是-ftree-loop-distribute-patterns

执行可以通过调用库生成代码的模式的循环分布。默认情况下,此标志在 -O2 及更高级别以及由-fprofile-use和启用-fauto-profile

所以一个人的解决方案是降低优化级别。不是很满意。

我还发现这真的有用的网页,说明这-ffreestanding是不足以让GCC没有做到这一点,而且也根本没有选择,只能提供自己的实现memcpymemmovememsetmemcmp。我很乐意这样做,但是怎么做?

如果我只是编写memset编译器将检测其中的循环并将其转换为对 memset 的调用!事实上,在我使用的 CPU 供应商提供的代码中,我发现了这条评论:

/*
// This is commented out because the assembly code that the compiler generates …
Run Code Online (Sandbox Code Playgroud)

c gcc memset

37
推荐指数
1
解决办法
1128
查看次数

以编程方式与Android 4.4+上的BLE设备配对

有没有人有一个完整的工作示例,说明如何以编程方式配对使用密码输入(即6位数PIN)或Android 4.4或更高版本的数字比较的BLE( Bluetooth Classic)设备?通过'以编程方式'我的意思是我告诉Android PIN - 用户不会被提示.

在SO上有很多类似的问题,但它们要么a)关于蓝牙经典,b)旧(之前setPin()createBond()公开),或c)未答复.

我的理解如下.

  1. 您连接到设备并发现其服务.
  2. 您尝试阅读"受保护"特征.
  3. 设备返回身份验证错误.
  4. Android以某种方式启动配对,你告诉它PIN.
  5. 您现在可以阅读该特征.

我已经使用创建设备mBed上运行nRF51-DK和赋予它的单个特性.

我设置了安全参数,如下所示:

ble.securityManager().init(
    true, // Enable bonding (though I don't really need this)
    true, // Require MitM protection. I assume you don't get a PIN prompt without this, though I'm not 100% sure.
    SecurityManager::IO_CAPS_DISPLAY_ONLY, // This makes it us the Passkey Entry (PIN) pairing method.
    "123456"); // Static PIN
Run Code Online (Sandbox Code Playgroud)

然后在我使用的特征

requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM);
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试使用Nordic Master Control Panel阅读它时,我收到一个如下配对请求通知: …

android bluetooth bluetooth-lowenergy pairing

32
推荐指数
2
解决办法
2万
查看次数