我有两个使用Xamarin.Android编写的独立应用程序;为了便于讨论,我们将它们称为“ Tristan”和“ Isolde”。特里斯坦(Tristan)有一些伊索尔德有时需要知道的状态信息。并发症:在Isolde发展了解自己状态的需求的那一刻,Tristan可能正在跑步,也可能未跑步。
我现在正在忙着工作,在这里Isolde向Tristan发送了一个特殊的发射意图,然后Tristan使用广播意图将信息发送回Isolde。 (有关详细信息,请参见我的earlier question。)
“但是等等!”我听到你在哭,“这不是StartActivityForResult()
的完美用例吗?”它的确是!该代码非常简单,我读过的所有内容都暗示着这就是Android希望您执行此类操作的方式。
不幸的是,我无法使用它(尽管尝试了许多变体并阅读了该站点上的十几个相关问题)。我的具体问题是,在Isolde的OnActivityResult()
回调中,resultCode
始终为Result.Canceled
,而data
始终为null
。
这里是Tristan的代码(其中注释掉的位代表我尝试过的变体):
using Android.App;
using Android.Content;
namespace com.example.Tristan.Android
{
[Activity(Name ="com.example.Tristan.Android.IsoldeQueryActivity")]
public class IsoldeQueryActivity : Activity
{
protected override void OnStart()
{
// base.OnStart();
var rtn = new Intent();
rtn.PutExtra("Test", "test");
//rtn.SetAction("TestAction");
SetResult(Result.Ok, rtn);
Finish();
//FinishActivity(1234);
}
}
}
下面是Activity
中的相关代码,Isolde需要询问Tristan的状态:
private TaskCompletionSource<bool> TristanStateCompletion;
public async Task GetTristanState()
{
TristanStateCompletion = new TaskCompletionSource<bool>();
var req = new Intent("com.example.Tristan.Android.IsoldeQueryActivity");
//req.PutExtra(Intent.ExtraReturnResult, true);
StartActivityForResult(req, 1234);
var rtn = await TristanStateCompletion.Task;
if (!rtn) bomb("can't get state");
TristanStateCompletion = null;
}
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if(requestCode == 1234) {
DoStuffWith(data);
TristanStateCompletion?.TrySetResult(true);
}
}
诊断程序-或更确切地说,缺少诊断程序-使我相信从未真正调用过Tristan的IsoldeQueryActivity.OnStart()
。
想法,要求提供其他信息和/或尝试进行有用的实验都将受到欢迎。 (如果您的想法是“在清单中放入Activity
的属性中放入
编辑后添加:在Isolde的代码中,DoStuffWith(data)
崩溃了,因为data
是null
。当我更改该方法以避免这种情况发生时,我发现StartActivityForResult()
中抛出了(稍后)一个异常:
Android.Content.ActivityNotFoundException No Activity found to handle Intent { act=com.example.Tristan.Android.IsoldeQueryActivity }
这使我相信我没有在Isolde中正确创建Intent
。我是否需要使用其他Intent
构造函数之一?如果是这样,具体如何?
答案 0 :(得分:0)
好的,我想我已经知道了。我最初的问题中的代码存在三个主要问题:
Intent
。IsoldeQueryActivity
。base.OnStart()
替代中,对OnStart
的调用是强制性的。这是Tristan的工作版本:
using Android.App;
using Android.Content;
namespace com.example.Tristan.Android
{
[Activity(Name ="com.example.Tristan.Android.IsoldeQueryActivity", Exported=true)]
public class IsoldeQueryActivity : Activity
{
protected override void OnStart()
{
base.OnStart();
var rtn = new Intent();
rtn.PutExtra("Test", "test");
SetResult(Result.Ok, rtn);
Finish();
}
}
}
这是来自Isolde的固定代码:
private TaskCompletionSource<bool> TristanStateCompletion;
public async Task GetTristanState()
{
TristanStateCompletion = new TaskCompletionSource<bool>();
var req = new Intent();
req.SetComponent(new ComponentName("com.example.Tristan.Android", "com.example.Tristan.Android.IsoldeQueryActivity"));
StartActivityForResult(req, 1234);
var rtn = await TristanStateCompletion.Task;
if (!rtn) bomb("can't get state");
TristanStateCompletion = null;
}
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if(requestCode == 1234) {
if(resultCode != Result.Ok) bomb("bad resultCode {0}", resultCode);
if(data == null) bomb("null data from Tristan");
DoStuffWith(data);
TristanStateCompletion?.TrySetResult(true);
}
}