我正在制作Xamarin.Android应用程序,并且我使用SQLite来处理某些图像(超过300个)。我将图像作为模板存储在一组5张图像中,如下所示:
[Table("Templates")]
public class Template
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public int Category { get; set; }
[OneToMany]
public List<TemplateImage> TemplateImages { get; set; }
public string ImagesHash { get; set; }
}
[Table("TemplateImages")]
public class TemplateImage
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public int Category { get; set; }
public int Image { get; set; }
[ForeignKey(typeof(Template))]
public int TemplateId { get; set; }
}
并且是第一次启动该应用程序时,我使用此代码来检查数据库是否存在或创建数据库:
public static void AddTemplate(int category, List<int> images)
{
var tmpl = new Template()
{
Category = category,
};
if (images != null)
{
var img1 = new TemplateImage()
{
Category = category,
Image = images[0],
};
var img2 = new TemplateImage()
{
Category = category,
Image = images[1],
};
var img3 = new TemplateImage()
{
Category = category,
Image = images[2],
};
var img4 = new TemplateImage()
{
Category = category,
Image = images[3],
};
var img5 = new TemplateImage()
{
Category = category,
Image = images[4],
};
tmpl.TemplateImages = new List<TemplateImage>() { img1, img2, img3, img4, img5 };
}
tmpl.ImagesHash = Guid.NewGuid().ToString();
DatabaseHelper.Db().InsertAll(tmpl.TemplateImages);
DatabaseHelper.Db().Insert(tmpl);
DatabaseHelper.Db().UpdateWithChildren(tmpl);
}
public static List<Template> GetAllTemplates()
{
return DatabaseHelper.Db().GetAllWithChildren<Template>();
}
public static Template GetTemplate(int id)
{
var result = DatabaseHelper.Db().GetWithChildren<Template>(id);
if (result == null)
{
result = DatabaseHelper.Db().GetAllWithChildren<Template>().Where(record => record.Category == (int)TemplateCategory.Emojis).OrderBy(record => record.Id).FirstOrDefault();
}
return result;
}
public static void CreateDB()
{
DatabaseHelper.Db().RunInTransaction(() =>
{
DatabaseHelper.Db().CreateTable<Template>();
DatabaseHelper.Db().CreateTable<TemplateImage>();
if (DatabaseHelper.Db().Table<Template>().Count() != 0)
{
return;
}
AddTemplate(
(int)TemplateCategory.Emojis,
new List<int>
{
Resource.Drawable.ic_angry,
Resource.Drawable.ic_sad,
Resource.Drawable.ic_neutral,
Resource.Drawable.ic_happy,
Resource.Drawable.ic_smiling,
}
);
AddTemplate(
(int)TemplateCategory.Emojis,
new List<int>
{
Resource.Drawable.ic_emoji_01_1,
Resource.Drawable.ic_emoji_01_2,
Resource.Drawable.ic_emoji_01_3,
Resource.Drawable.ic_emoji_01_4,
Resource.Drawable.ic_emoji_01_5,
}
);
...//AND many more AddTemplate() functions like those 2.
}
这很好用,直到有一天我在非常罕见的情况下看到了[[有时应用程序正在显示..其他图像,我从那些图像中随机选择了它。因此,我意识到出于某些原因,compiler决定要更改ImageDrawables的ResourceId,因此,尽管事实上我的数据库存在,但这是完全错误的,
因此,我已经开始重新考虑做这种事情的正确方法是什么,而不必每次都重新创建数据库时,我发现了每次坏数据库时都重新创建数据库的想法,但是如果这是唯一正确的方法,并且只有这样我才能100%确定结果,我会坚持下去。我从测试中看到,通常第一组图像已更改(第一个模板),我在考虑做这样的事情是否是一个好主意:
public static bool ExistingDBItemsFound(int id)
{
var returnValue = false;
var result = GetTemplate(1);
if (result.TemplateImages.Count == 5)
{
if (result.TemplateImages[0].Image == Resource.Drawable.ic_angry
&& result.TemplateImages[1].Image == Resource.Drawable.ic_sad
&& result.TemplateImages[1].Image == Resource.Drawable.ic_neutral
&& result.TemplateImages[1].Image == Resource.Drawable.ic_happy
&& result.TemplateImages[1].Image == Resource.Drawable.ic_smiling)
returnValue = true;
}
return returnValue;
}
但是如果我做这样的事情,我如何才能确保所有其他资源ID都是正确的?我只检查300个以上的5个。我是否可以避免在每次创建应用程序的数据库项时重新创建?我是怎么办?
有没有一种方法可以将资源以其他格式而不是resourceId的形式保存在数据库中?
解决我的问题的一种方法可能是使用此处的建议答案:Best way to store Resource id in Database on Android
获取图标名称
var iconName = Context.Resources.GetResourceEntryName( Resource.Drawable.your_icon );
然后从名称获取ID:
var id = Context.Resources.GetIdentifier( iconName, "drawable", Context.PackageName )
这样,即使资源ID发生变化,只要不重命名资源,我们都将获得正确的图像。[如果您还想检查用户数据库是否具有与apk数据库相同的值,则可以执行@martin venter建议的操作并以某种方式创建哈希(例如:资源名称的哈希)并进行比较]]