意图服务中的多个异步 Ado.net sql 插入
Multiple async Ado.net sql inserts in intent service
我有一个执行以下操作的意图服务:
从intent中提取一个字符串参数,
使用参数组成http查询,
使用异步任务执行它,System.Net.Http、
解析收到的 json 并将一些字段值放入字符串 sqlQuery 中,它将数据插入到 sqlite 数据库中,
使用 Ado.net 执行 sqlQuery(使用打开连接然后关闭连接的方法)。
请注意,可以有多个调用服务的意图,具有不同的 PutExtra 值。因此,activity 告诉服务:"Load information for City1"、"Load information for City2" ....等
更新。意图服务代码:
public WeatherService() : base("WeatherService")
{
}
public string sqlQuery;
protected override async void OnHandleIntent(Android.Content.Intent intent)
{
// Get extras
string wsMode = intent.GetStringExtra("mode");
string wsLocation = intent.GetStringExtra("location");
string wsProvider = intent.GetStringExtra("provider");
string wsUpdId = intent.GetStringExtra("upd_id");
//string debugMsg = "INTENT_SERVICE_OUTPUT: Mode " + wsMode + ", location " + wsLocation + " , provider " + wsProvider;
//Console.WriteLine(debugMsg);
// Generate http string
string httpQuery = "";
switch (wsProvider)
{
case "openweathermap":
httpQuery = "http://api.openweathermap.org/data/2.5/weather?&appid=1&units=metric&lang=ru"; //fake key here
if (wsMode == "code") { httpQuery = httpQuery + "&id=" + wsLocation; }
break;
default:
httpQuery = "";
break;
}
// Get weather from the provider
dynamic results = await DataService.getDataFromService(httpQuery);
if (results["weather"] != null)
{
// Compose insert queries
if (sqlQuery == null) { sqlQuery = ""; Console.WriteLine("SQL QUERY FROM NULL TO EMPTY STRING"); }
sqlQuery = sqlQuery +
"INSERT INTO [Weather] ([IND_ID], [UPD_ID], [CITY_ID], [VALUE], [SHOW], [DATE], [TIME]) " +
"SELECT [IND_ID],'" + wsUpdId + "','" + (string)results["id"] + "','" + (string)results["weather"][0]["description"] +
"',1,NULL,NULL FROM [Indicators] WHERE [CAPTION] = 'currentConditions';" +
"INSERT INTO [Weather] ([IND_ID], [UPD_ID], [CITY_ID], [VALUE], [SHOW], [DATE], [TIME]) " +
"SELECT [IND_ID],'" + wsUpdId + "','" + (string)results["id"] + "','" + (string)results["main"]["temp"] +
"',1,NULL,NULL FROM [Indicators] WHERE [CAPTION] = 'currentTemperature';";
Console.WriteLine(sqlQuery);
}
}
public override void OnDestroy()
{
// Insert data into databse
if (sqlQuery != null) { Sql.ExecQueryScalarOrNonQuery(sqlQuery, 0); Console.WriteLine("SQL_QUERY: INSERTED"); } else { Console.WriteLine("SQL_QUERY: EMPTY!!!"); }
// Update current view
// TODO
// End Service
base.OnDestroy();
因此,如您所见,我尝试声明一个名为 sqlQuery 的字符串,并尝试在其中插入一些数据。但问题是:要正确询问 http 异步任务,我必须使所有 OnHandleIntent 方法
protected override async void OnHandleIntent()
因此,OnHandleIntent 已启动并且 OnDestroy() 立即启动,此时 sqlQuery 仍为空!!!就在几秒钟前,OnHandleIntent-s(在我的例子中是两个)完成了。
那么,如何进行以下操作:在 OnHandleIntent 中我们获取额外的内容,生成并启动 http 查询(在 not 上使用异步任务???),然后我们为 db 生成并保存插入(为简单起见,让我们做那在字符串 sqlQuery 中;))。然后,当所有 OnHandleIntents 准备就绪时,我们执行最终的 sqlQuery(一次)并通过调用 base.OnDestroy() 结束服务。提前致谢。
我决定将方法声明更改为
protected override void
并重写 DataService class 以进行异步 -> 同步,如下所示:
public class DataService
{
public static object ReceivedData(string queryString)
{
// Exec the query
dynamic data = null;
using (HttpClient client = new HttpClient())
{
var response = client.GetAsync(queryString).Result;
// If result is not null, deserialize json
if (response != null)
{
string json = response.Content.ReadAsStringAsync().Result;
data = JsonConvert.DeserializeObject(json);
}
}
// Return json result
return data;
}
}
在我的例子中,所有的工作(同步)都在意图服务的线程中,然后成功插入到本地 sqlite 数据库(在 intentservice 的 OnDestroy() 方法中。
我有一个执行以下操作的意图服务:
从intent中提取一个字符串参数,
使用参数组成http查询,
使用异步任务执行它,System.Net.Http、
解析收到的 json 并将一些字段值放入字符串 sqlQuery 中,它将数据插入到 sqlite 数据库中,
使用 Ado.net 执行 sqlQuery(使用打开连接然后关闭连接的方法)。
请注意,可以有多个调用服务的意图,具有不同的 PutExtra 值。因此,activity 告诉服务:"Load information for City1"、"Load information for City2" ....等
更新。意图服务代码:
public WeatherService() : base("WeatherService")
{
}
public string sqlQuery;
protected override async void OnHandleIntent(Android.Content.Intent intent)
{
// Get extras
string wsMode = intent.GetStringExtra("mode");
string wsLocation = intent.GetStringExtra("location");
string wsProvider = intent.GetStringExtra("provider");
string wsUpdId = intent.GetStringExtra("upd_id");
//string debugMsg = "INTENT_SERVICE_OUTPUT: Mode " + wsMode + ", location " + wsLocation + " , provider " + wsProvider;
//Console.WriteLine(debugMsg);
// Generate http string
string httpQuery = "";
switch (wsProvider)
{
case "openweathermap":
httpQuery = "http://api.openweathermap.org/data/2.5/weather?&appid=1&units=metric&lang=ru"; //fake key here
if (wsMode == "code") { httpQuery = httpQuery + "&id=" + wsLocation; }
break;
default:
httpQuery = "";
break;
}
// Get weather from the provider
dynamic results = await DataService.getDataFromService(httpQuery);
if (results["weather"] != null)
{
// Compose insert queries
if (sqlQuery == null) { sqlQuery = ""; Console.WriteLine("SQL QUERY FROM NULL TO EMPTY STRING"); }
sqlQuery = sqlQuery +
"INSERT INTO [Weather] ([IND_ID], [UPD_ID], [CITY_ID], [VALUE], [SHOW], [DATE], [TIME]) " +
"SELECT [IND_ID],'" + wsUpdId + "','" + (string)results["id"] + "','" + (string)results["weather"][0]["description"] +
"',1,NULL,NULL FROM [Indicators] WHERE [CAPTION] = 'currentConditions';" +
"INSERT INTO [Weather] ([IND_ID], [UPD_ID], [CITY_ID], [VALUE], [SHOW], [DATE], [TIME]) " +
"SELECT [IND_ID],'" + wsUpdId + "','" + (string)results["id"] + "','" + (string)results["main"]["temp"] +
"',1,NULL,NULL FROM [Indicators] WHERE [CAPTION] = 'currentTemperature';";
Console.WriteLine(sqlQuery);
}
}
public override void OnDestroy()
{
// Insert data into databse
if (sqlQuery != null) { Sql.ExecQueryScalarOrNonQuery(sqlQuery, 0); Console.WriteLine("SQL_QUERY: INSERTED"); } else { Console.WriteLine("SQL_QUERY: EMPTY!!!"); }
// Update current view
// TODO
// End Service
base.OnDestroy();
因此,如您所见,我尝试声明一个名为 sqlQuery 的字符串,并尝试在其中插入一些数据。但问题是:要正确询问 http 异步任务,我必须使所有 OnHandleIntent 方法
protected override async void OnHandleIntent()
因此,OnHandleIntent 已启动并且 OnDestroy() 立即启动,此时 sqlQuery 仍为空!!!就在几秒钟前,OnHandleIntent-s(在我的例子中是两个)完成了。
那么,如何进行以下操作:在 OnHandleIntent 中我们获取额外的内容,生成并启动 http 查询(在 not 上使用异步任务???),然后我们为 db 生成并保存插入(为简单起见,让我们做那在字符串 sqlQuery 中;))。然后,当所有 OnHandleIntents 准备就绪时,我们执行最终的 sqlQuery(一次)并通过调用 base.OnDestroy() 结束服务。提前致谢。
我决定将方法声明更改为
protected override void
并重写 DataService class 以进行异步 -> 同步,如下所示:
public class DataService
{
public static object ReceivedData(string queryString)
{
// Exec the query
dynamic data = null;
using (HttpClient client = new HttpClient())
{
var response = client.GetAsync(queryString).Result;
// If result is not null, deserialize json
if (response != null)
{
string json = response.Content.ReadAsStringAsync().Result;
data = JsonConvert.DeserializeObject(json);
}
}
// Return json result
return data;
}
}
在我的例子中,所有的工作(同步)都在意图服务的线程中,然后成功插入到本地 sqlite 数据库(在 intentservice 的 OnDestroy() 方法中。