我有一个活动可能会在用户按下并完成()活动时运行线程.那时候那些线程会发生什么?除非我在onDestroy()中断它们,否则它们都会尝试完成吗?
例如,下面的代码是不安全的,因为如果活动在线程之前完成,我的视图和游标可能会被销毁?
我问的原因是我在完成尚未成功调试的活动时偶尔会崩溃,因为它们很少发生,而且从未在我处于调试模式时发生.我已经开始检查我的视图对象是否为null,然后在runOnUIThread()中对它们执行任何操作.不确定这是否是最干净的解决方案,或者根本不是问题.
new Thread()(
public void run(){
crunchOnSomethingForAwhile(mCursor);
MyActivity.this.runOnUIThread(new Runnable(){
public void run(){
mTextView.setText("thread complete");
mCursor.close();
}
}
}
).start();
Run Code Online (Sandbox Code Playgroud) 我正在开发一个针对API 11(3.0)的应用程序,但minSDKVersion为7(2.1).
我以编程方式而不是XML方式生成PreferenceActivity.在Honeycomb中,首选项布局有一个内置的图标位置,可以在每个首选项旁边显示.您可以使用它进行设置prefScreen.setIcon(R.drawable.my_icon);
所以我不想在API 7-10上这样做.这是否足以防止崩溃?
if (android.os.Build.VERSION.SDK_INT>=11)
prefScreen.setIcon(R.drawable.myIcon);
Run Code Online (Sandbox Code Playgroud)
我知道更安全的解决方案是在尝试使用它之前使用反射来检查该方法是否存在.
在Android中,我可以安全地从不同的线程访问和修改基本类型.我用它在我的OpenGL绘制循环和在主线程Android UI中修改的用户设置之间共享数据.通过将每个设置存储在基本类型中并使每个设置独立于其他值,在不使用锁或synchronize关键字的情况下修改所有这些变量是线程安全的.
在Objective-C中也是如此吗?我读到将atomic放在变量上实质上会导致合成的getter和setter使用锁,类似于在Java中使用synchronized方法.我已经读过这个原因是因为一个对象在被另一个线程读取时不会被部分修改.
但原始类型是否可以安全地被部分修改,因为它们在Java中?如果是这种情况,似乎我可以使用Java中的相同旧范例在线程之间共享数据.但是原子关键字对于一个原始关键字是没有意义的,对吗?
我还读到,比使用原子变量更强大,更快的解决方案是在使用它们之前复制对象(如果从多个线程访问它们).但我不确定如何才能实现.非原子对象在复制过程中是否无法被修改,从而破坏了副本?
MTAudioProcessingTap的头文件说它的初始化和准备回调将通过无准备和最终化回调来平衡.但是,在Apple的例子中,这些回调永远不会被调用(我添加了对它们的记录,所以我可以检查).头文件表示在取消分配对象时将调用它们.
在Apple的示例中,Tap被传递到audioMixInputParameters中的retain参数,该参数被传递到音频混合中,在那里它不再可公开访问:
MTAudioProcessingTapRef audioProcessingTap;
if (noErr == MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks, kMTAudioProcessingTapCreationFlag_PreEffects, &audioProcessingTap))
{
audioMixInputParameters.audioTapProcessor = audioProcessingTap;
CFRelease(audioProcessingTap);
audioMix.inputParameters = @[audioMixInputParameters];
_audioMix = audioMix;
}
Run Code Online (Sandbox Code Playgroud)
我希望AudioMix负责在自己的dealloc方法中释放它,并在发布相关的PlayerItem时释放AudioMix.
Apple的例子使用的AVPlayer只播放一个项目,所以也许它不需要直接释放任何东西.但在我的情况下,我正在使用AVQueuePlayer,所以我不断传递新的AVPlayerItems.我认为它正在泄漏我为每个玩家项目创建的Taps(以及相关的音频单元),即使播放器项目被取消分配.
当我完成其关联的播放器项目时,解除MTAudioProcessingTap并获取其无准备和最终确定的回调的正确方法是什么?
更新:我发现它实际上仍然可以通过音频混合访问,但是像这样释放它不会触发无准备和最终的回调:
((AVMutableAudioMixInputParameters *)audioMix.inputParameters[0]).audioTapProcessor = nil;
Run Code Online (Sandbox Code Playgroud)
这也不是:
MTAudioProcessingTapRef audioProcessingTap = ((AVMutableAudioMixInputParameters *)audioMix.inputParameters[0]).audioTapProcessor;
CFRelease(audioProcessingTap);
Run Code Online (Sandbox Code Playgroud) 在我的OpenGL循环,仪器是表示我的粒子处理循环去一个总的我的处理器时间的14%objc_object::sidetable_release(bool)和objc_object:sidetable_retain().这很重要,因为循环使用iPhone 5上100%的CPU.
我想知道是否有办法减少这种情况.我不知道是什么导致它,我在很多方法中都没有看到这些.我认为它们与快速枚举对象数组有关.
这是违规方法的样子:
-(void) updateWithTime:(ccTime)dt sceneHeightAboveHorizon:(CGFloat)yMax{
_elapsed = (_elapsed+dt) ;
float farTotalWidth = EQ_SCENE_WIDTH + 2*EQ_SIZE_FAR;
float farHalfWidth = farTotalWidth/2.0;
for (MyParticleData *data in self.farParticleData){
//Calculate position
float newX = data.pos.x + data.xVelocity * dt;
if (newX > 1)
newX -= 1;
float newY = data.y0 + EQ_A_FAR*sin(EQ_F_FAR*_elapsed+data.phasePosition);
data.pos = cc3v(newX,newY,0);
//Apply new position to sprites
data.sprite.position = cc3v(newX*farTotalWidth-farHalfWidth, newY*yMax, 0);
data.reflectedSprite.position = cc3v(data.sprite.position.x,-data.sprite.position.y,0);
//Calculate color
float f = MIN(14, MAX(data.pos.x*14.0, 0));
ccColor4F newColor = …Run Code Online (Sandbox Code Playgroud) Google Play 结算库以前不需要该android.permission.INTERNET许可。在 6.0 版本中,我可以从合并的清单中看到,现在确实如此。
它的来源是来自名为 的清单文件transport-backend-cct:3.1.8。谷歌搜索告诉我它是 Firebase 的一部分,但我没有使用它。也许计费库现在在底层使用 Firebase。
我想避免这种情况的原因是我的一个应用程序使用麦克风。我担心如果我在批准麦克风权限后在更新中“偷偷地”添加互联网权限,我的客户会感到震惊。
也许这可能性不大,但是否可以避免使用此权限并仍然使用 Google Play 结算服务?
在我阅读的大多数Objective-C示例中,以及Objective-C文档中,始终在使用前检查对象是否成功完成.
例如:
MyObject *myObject = [[MyObject alloc] init];
if (myObject){
//do stuff with the object
}
//stuff beyond here is probably not going to work if myObject is nil
Run Code Online (Sandbox Code Playgroud)
这会不会很难追踪错误?我不确定除了内存不足之外,为什么分配会失败,但是在初始化对象之后,我从来没有在Java(我正在迁移的语言)中看到这样的检查.
我想如果你检查每一个分配并尝试对失败的分配做出反应,它会使应用程序变得非常复杂.我猜你可以在很多情况下向用户显示错误信息,但程序中的分支数量可能会翻倍.
但是在我看过的例子中,他们在分配失败时没有做任何事情,除了跳过一些代码,这些代码对于用户在屏幕上看到他们期望的内容是必要的.看起来如果失败的分配在实践中确实发生了很多,并且你遵循这种编码风格,结果将是空白屏幕,用户认为已保存的未保存文档,用户和程序员不知道的损坏数据,等等
编辑:这是Apple的教程"你的第三个iOS应用程序:iCloud"的一个例子.
- (NSMetadataQuery*)textDocumentQuery {
NSMetadataQuery* aQuery = [[NSMetadataQuery alloc] init];
if (aQuery) {
// Search the Documents subdirectory only.
[aQuery setSearchScopes:[NSArray
arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
// Add a predicate for finding the documents.
NSString* filePattern = [NSString stringWithFormat:@"*.%@",
STEDocFilenameExtension];
[aQuery setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE %@",
NSMetadataItemFSNameKey, filePattern]];
}
return aQuery;
}
Run Code Online (Sandbox Code Playgroud) 我有一个本机函数(来自库),它在uint8_t类型上做了一些工作(无符号8位数0-255).Java最接近的是必须签名的字节.
如何将此字节转换为适当的正整数以在Java中使用?我知道我必须将它存储在short或int中才能正确表示0-255之间的数字,但我不知道如何转换字节.
我试过int intValue = byteValue & 0xFF;,但这给了我意想不到的结果,所以我怀疑这是不正确的.或者这是正确的,我误解了本机库函数的预期结果.无论如何都会欣赏确认.
我知道建议将 ViewModel 与我们的 Activity 一起使用,因此我们可以使用它的viewModelScope. 由于 ViewModel 比活动寿命更长,我们不必取消activity.onDestroy().
但是,有时您会遇到非常简单的 Activity。例如,它可以使用已安装的过滤包填充列表视图。您可以非常简单地使用委托为活动创建一个范围,并在onDestroy()以下位置取消作业:
class MyActivity(): AppCompatActivity(), CoroutineScope by MainScope() {
private val listAdapter = MyAdapter()
override fun onCreate() {
super.onCreate()
setContentView(R.layout.my_activity)
recycler_view.apply {
layoutManager = LinearLayoutManager(this)
adapter = listAdapter
}
launch {
val packages = getOrgPackagesWithIcons()
adapter.apply {
data = packages
notifyDataSetChanged()
}
}
}
override fun onDestroy() {
super.onDestroy()
cancel() // CoroutineContext
}
private suspend fun getOrgPackagesWithIcons() = withContext(Dispatchers.Default) {
var toNextYield = 20
packageManager.getInstalledPackages(0)
.filter …Run Code Online (Sandbox Code Playgroud) 我完全按照教程进行操作。我在 .xml 下的布局 XML 文件中为视图命名android:id。当我在 Kotlin 中输入该名称时,它会以红色突出显示,并且出现“未解析的引用”错误。
例如,在 XML Activity_main.xml中:
<TextView
android:id="@+id/nameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Run Code Online (Sandbox Code Playgroud)
在 Kotlin MainActivity.kt中:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
nameTextView // <-- This is highlighted red with error so I can't use it!
}
Run Code Online (Sandbox Code Playgroud)
我创建这个问题是因为自从 Kotlin Android 扩展被弃用以来,我已经多次看到它的变体,但它们的措辞方式多种多样,并且不太容易搜索。我认为共同的因素是新的 Android 程序员遵循弃用之前编写的教程。这些教程通常不会指定所使用的功能称为合成属性或Kotlin Android 扩展、合成视图属性或kotlin-android-extensions,并且该功能已被弃用。
android ×5
objective-c ×4
ios ×2
kotlin ×2
avfoundation ×1
c++ ×1
google-play ×1
instruments ×1
java ×1
macos ×1
optimization ×1
xml ×1