- 浏览: 160246 次
- 性别:
- 来自: 重庆
文章分类
最新评论
-
坏猪猪:
Document doc = Jsoup.connect(ur ...
android中jsoup解析html的几个例子 -
我很温柔但是不丑:
你好。看了您的例子,实践了一下,有问题啊?没有解析出来数据?怎 ...
android中jsoup解析html的几个例子
初始MIME类型,是在学习ContentProvider的时候。
当在创建自己的ContentProvider的时,需要从抽象类ContentProvider中派生出自己的子类,并实现其中5个抽象方法:
query(Uri, String[], String, String[], String) which returns data to the caller
insert(Uri, ContentValues) which inserts new data into the content provider
update(Uri, ContentValues, String, String[]) which updates existing data in the content provider
delete(Uri, String, String[]) which deletes data from the content provider
getType(Uri) which returns the MIME type of data in the content provider
至于前四个方法,不是本文想要讨论的重点,就不做冗余的阐述了;有意思的是这个方法getType(Uri),根据帮助文档的解释,它返回一个MIME类型。
首先,先百度了一下MIME类型,根据百度百科的解释:MIME:全称Multipurpose Internet Mail Extensions,多功能Internet 邮件扩充服务。它是一种多用途网际邮件扩充协议,在1992年最早应用于电子邮件系统,但后来也应用到浏览器。MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
看完百度百科的解释,相信大家和我一样,仍然不解。结合一个例子和跟老师的交流,我的理解是这样的:
在ContentProvider的getType(Uri)方法中,可以显示的返回一个MIME类型,该方法返回一个字符串,可以是任意的字符串,当我们显示的返回一个MIME类型的时候,相当于通过该方法的验证,Provider可以识别Provider中其他方法返回的Cursor的内容,不需要在进行更多的验证;如果返回其他的字符串(非android能够识别的MIME类型,例如直接返回当前的包名),则Provider在执行其他方法后,返回Cursor类型的时候,需要进行验证。
还是云里雾里的?下面来看一个使用了MIME类型的自定义ContentProvider的例子:
import android.net.Uri;
public class Shopping {
// 定义数据库的名字
public static final String DATABASE_NAME = "shopping_db";
// 定义数据库的版本
public static final int DATABASE_VERSION = 1;
// 表的名字
public static final String TABLE_NAME = "t_shopping";
// 定义数据库的字段
public static final String FIELD_ID = "_id";
public static final String FIELE_NAME = "product_name";
// 定义访问的类型
public static final int ITEM = 1;
public static final int ITEM_ID = 2;
// 定义MIME类型,访问单个记录
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.stone.shopping";
// 访问数据集
public static final String CONTENT_ITEM = "vnd.android.cursor.dir/vnd.stone.shopping";
// 定义访问ContentProvider权限
public static final String AUTHORITY = "com.stone.shopping";
// 定义URI
public static final Uri URI = Uri.parse("content://" + AUTHORITY + "/item");
}
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
public class MyDbHelper extends SQLiteOpenHelper {
public MyDbHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE " + Shopping.TABLE_NAME + " ( "
+ Shopping.FIELD_ID + " INTEGER primary key autoincrement, "
+ " " + Shopping.FIELE_NAME + " TEXT)";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String sql = "DROP TABLE IF EXISTS " + Shopping.TABLE_NAME;
db.execSQL(sql);
onCreate(db);
}
}
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.text.TextUtils;
public class MyProvider extends ContentProvider {
private MyDbHelper myDbHelper;
private static final UriMatcher mUriMatcher; // 进行匹配的Uri的设定
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(Shopping.AUTHORITY, "item", Shopping.ITEM);
mUriMatcher.addURI(Shopping.AUTHORITY, "item/#", Shopping.ITEM_ID);
}
@Override
public boolean onCreate() {
System.out.println("onCreate");
// 创建数据库
myDbHelper = new MyDbHelper(getContext(), Shopping.DATABASE_NAME, null,
Shopping.DATABASE_VERSION);
return true;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = myDbHelper.getWritableDatabase();
int count = 0;
System.out.println("delete");
switch (mUriMatcher.match(uri)) {
case Shopping.ITEM:
count = db.delete(Shopping.TABLE_NAME, selection, selectionArgs);
break;
case Shopping.ITEM_ID:
// 通过Uri获取Id,根据主键进行删除
String id = uri.getPathSegments().get(1);
System.out.println(String.valueOf(uri.getPathSegments().size()));
count = db.delete(Shopping.TABLE_NAME,
Shopping.FIELD_ID + "=" + id, selectionArgs);
break;
default:
throw new IllegalArgumentException();
}
// 通知数据发生改变
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = myDbHelper.getWritableDatabase();
long row = 0;
System.out.println("insert");
if (mUriMatcher.match(uri) != Shopping.ITEM) {
throw new IllegalArgumentException();
}
row = db.insert(Shopping.TABLE_NAME, Shopping.FIELD_ID, values);
if (row > 0) {
Uri noteUri = ContentUris.withAppendedId(Shopping.URI, row);
getContext().getContentResolver().notifyChange(uri, null);
return noteUri;
}
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = myDbHelper.getReadableDatabase();
Cursor cursor = null;
System.out.println("query");
switch (mUriMatcher.match(uri)) {
case Shopping.ITEM:
cursor = db.query(Shopping.TABLE_NAME, projection, selection,
selectionArgs, null, null, sortOrder);
break;
case Shopping.ITEM_ID:
String id = uri.getPathSegments().get(1);
cursor = db.query(Shopping.TABLE_NAME, projection,
Shopping.FIELD_ID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND ("
+ selection + ')' : ""), selectionArgs,
null, null, sortOrder);
break;
default:
throw new IllegalArgumentException();
}
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = myDbHelper.getWritableDatabase();
int count = 0;
System.out.println("update");
switch (mUriMatcher.match(uri)) {
case Shopping.ITEM:
count = db.update(Shopping.TABLE_NAME, values, selection,
selectionArgs);
break;
case Shopping.ITEM_ID:
String id = uri.getPathSegments().get(1);
count = db.update(Shopping.TABLE_NAME, values, Shopping.FIELD_ID
+ "="
+ id
+ (!TextUtils.isEmpty(selection) ? " AND (" + selection
+ ')' : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException();
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
// 进行Uri匹配完成不同的处理工作
switch (mUriMatcher.match(uri)) {
case Shopping.ITEM:
return Shopping.CONTENT_ITEM;
case Shopping.ITEM_ID:
return Shopping.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException();
}
}
}
在上面的例子中,首先有一个Shopping类,定义了一系列的常量。包括访问的数据库的相关信息和URI的定义,其中最重要的就是下面的两句,MIME类型的定义:
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.stone.shopping";
public static final String CONTENT_ITEM = "vnd.android.cursor.dir/vnd.stone.shopping";
其次是一个MyDbHelper类,继承自SQLiteOpenHelper类,用于一些数据库相关操作,这里就不赘述了。
最后的MyProvider类使我们的重头戏,首先我们来看这一段代码:
private static final UriMatcher mUriMatcher; // 进行匹配的Uri的设定
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(Shopping.AUTHORITY, "item", Shopping.ITEM);
mUriMatcher.addURI(Shopping.AUTHORITY, "item/#", Shopping.ITEM_ID);
}
UriMatcher表示一个Uri的匹配器,它会对我们请求的Uri进行匹配,而匹配的格式就是这里我们通过addURI()方法添加格式。
接下来,首先执行的就是getType(Uri)方法,下面来看该方法体中的代码:
switch (mUriMatcher.match(uri)) {
case Shopping.ITEM:
return Shopping.CONTENT_ITEM;
case Shopping.ITEM_ID:
return Shopping.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException();
}
当请求过来的Uri通过mUriMatcher.match(uri)方法进行匹配,根据不同的匹配值(Shopping.CONTENT_ITEM 或者 Shopping.CONTENT_ITEM_TYPE)来返回不同的MIME类型。
下面我们来结合query(Uri, String[], String, String[], String) 这个方法来解释一下:
在这个方法中,返回的是一个Cursor游标对象。而Cursor中是单条的记录还是一个集合,需要和在getType()方法中返回的类型保持一致。当返回的MIME类型是Shopping.CONTENT_ITEM时,Cursor应该是一个集合;当返回的MIME类型是Shopping.CONTENT_ITEM_TYPE时,Cursor应该是单条记录。
由于在getType()方法里面,我们显示的返回了android平台可以识别的MIME类型,所以在执行query方法返回Cursor对象的时候,系统将不需要再进行验证,从而可以说是节省了系统开销。
话已至此,那么何谓android平台可以识别的MIME类型呢?下面来分析一下MIME类型的结构:
其实,MIME类型其实就是一个字符串,中间有一个 “/” 来隔开,“/”前面的部分是系统识别的部分,就相当于我们定义一个变量时的变量数据类型,通过这个“数据类型”,系统能够知道我们所要表示的是个什么东西。至于 “/” 后面的部分就是我们自已来随便定义的“变量名”了。
那么,既然MIME类型就是一个字符串,那么我们的getType( )自然也可以随便返回一个系统不能识别的字符串啦?没错,有些时候我们确实也这样处理,比如说可以这样写:
public String getType(Uri uri) {
return getContext().getPackageName();
}
这里,我们把当前上下文的包名返回了。这样处理的结果是怎样的呢?
简单的说,系统不能够识别它了,也就不会做任何处理。仍然以query方法来说,当执行完方法体(这里需要注意一下:在这种情况下,即使我们没有通过返回MIME类型字符串来进行验证处理,但是在query方法中再次对Uri进行了匹配并根据不同的Uri类型进行了不同的操作)返回Cursor对象的时候,这时候系统不能肯定返回的Cursor对象是否合法,因此需要对其进行验证,这样对系统资源算是一个浪费了吧。所以,我们最好还是显示的返回一个MIME类型吧,当然要写正确了,让我们android平台可以识别。
发表评论
-
Android中dip(dp)与px之间单位转换
2012-04-30 14:35 1560Android中dip(dp)与px之间单位转换 dp这个单 ... -
java字符串处理(分割截取替换等)
2012-01-06 17:04 20555/** * 分割字符串 * * @pa ... -
android database leak found
2012-01-06 09:52 1763package com.archermind; imp ... -
android中context
2012-01-04 19:48 2305我找了很多资料,还是不能弄懂,记下来,以后慢慢理解。 Con ... -
android中易错点
2012-01-03 10:58 13601.字符串匹配: equals和==是有区别的 用jsou ... -
android中jsoup解析html的几个例子
2012-01-03 10:58 393531.获取百度所有链接的例子(通过ID): public cl ... -
【Android】Uri、UriMatcher、ContentUris详解
2011-12-15 10:26 51781.Uri 通用资源标志 ... -
ContentProvider和ContentResolver还有SQLiteDatabase的关系
2011-12-14 22:51 1362在Android系统中,存储数据的方式一共有5种:1.Shar ...
相关推荐
`loadData()`需要三个参数:HTML字符串、MIME类型(通常是"text/html")和字符集(如"UTF-8")。`loadDataWithBaseURL()`则多了个基础URL,用于处理相对URL。在iOS中,WKWebView有`loadHTMLString:baseURL:`方法,...
- `BasicBodyPart`:用于创建HTTP实体的基本部分,它可以封装任何类型的输入流或字符串。 5. **示例代码** 下面是一个简单的使用httpmime-4.3.jar上传文件的Java代码示例: ```java import org.apache....
邮件中,每种正文类型都被封装在边界字符串`=====002_Dragon307572345230_=====`的前后,每个部分都有各自的`Content-Type`和`Content-Transfer-Encoding`,以便正确地编码和解码。 例3则进一步扩展了MIME的使用,...
1. **多部分编码**:MIME 邮件允许包含多个部分,每个部分都有独立的数据类型和编码方式,通过边界字符串分隔。 2. **媒体类型**:MIME 引入了媒体类型的概念,如 "text/plain" 表示纯文本,"image/jpeg" 表示 JPEG ...
1. **MIME类型(MIME Type)**:MIME类型是一个字符串,用于标识文件的类型。例如,"text/plain"表示纯文本,"image/jpeg"表示JPEG图片。在邮件中,每个部分都有一个对应的MIME类型,用来告诉邮件服务器或客户端如何...
接下来,httpmime-4.1.1还提供了FileBody和StringBody等类,用于封装文件和字符串内容,作为MIME实体的一部分。这些类简化了将本地文件或字符串内容转换为HTTP请求体的过程。例如,FileBody允许你直接指定一个文件...
**Base64编码** 是另一种广泛使用的编码技术,它将任意二进制数据转换为一种包含64个字符的ASCII字符串。这64个字符包括大小写字母、数字以及"+"和"/",最后还会用"="作为填充字符。Base64编码的主要优点是所有字符...
它可能会有一个`Encode`函数,接受二进制数据或字符串作为输入,返回Base64编码后的字符串。 2. `Base64Decoder` 类:负责将Base64编码的字符串解码回原始二进制数据。它可能包含一个`Decode`函数,接受Base64编码...
MIME还引入了Base64编码,用于将二进制数据转换为ASCII字符串,以便在电子邮件中安全传输。 在.NET 2.0中,我们可以通过System.Net.Mail命名空间下的类来处理MIME邮件。SmtpClient类用于发送邮件,而MailMessage类...
2. **调用函数SCMS_STRING_TO_XSTRING**:这个函数用于将字符串转换为二进制数据。函数的参数包括待转换的文本i_datain、MIME类型lv_mimetype以及用于接收二进制数据的缓冲区lstr_tmp。 3. **异常处理**:如果函数...
这个版本(2.4)可能相对较老,但依然包含许多常用的功能,如字符串操作、数组处理、日期和时间处理、反射工具、数学操作等。其中的一些关键类包括`StringUtils`、`ArrayUtils`、`DateUtils`和`ClassUtils`。开发者...
这两个类位于`java.net`包下,可以帮助开发者进行字符串编码和解码,确保数据在网络传输过程中的正确性。 `URLEncoder`类提供了`encode`静态方法,用于将普通字符串编码成`application/x-www-form-urlencoded` MIME...
3. **解码原理**:解码过程与编码相反,从Base64字符串中读取4个字符一组,根据Base64字符集将其转换回6位的十进制数,再组合成原始的24位数据。末尾的填充字符("=")表示剩余的位数不足24位,应相应地减少输出的...
4. **错误处理:**代码片段中提到了语法错误和意外的字符串类型问题。这通常是由于PHP代码中的语法错误导致的,例如对象属性引用的不正确写法。正确的写法应该是使用括号而不是等号,即`$code->decode_mime('subject...
- **Charset**:字符串类型,指定邮件的字符集,如“utf-8”,“gb2312”等。 - **ContentTransferEncoding**:字符串类型,设定邮件内容的传输编码方式。 - **ContentType**:字符串类型,定义邮件的格式,如"text/...
例如,当一个Java应用需要接收包含JSON数据的电子邮件时,`javax.mail.jar`用于接收邮件,`activation-1.1.1.jar`处理邮件内容的MIME类型,然后`fastjson-1.2.79.jar`将JSON字符串转化为Java对象以便进一步处理。...
4. **StringUtil.java**:字符串处理是编程中的基础,此类可能包含了一系列对字符串的操作,如空格处理、格式化、比较等。在JSON处理中,字符串操作往往用于清理或验证JSON字段的值。在AJAX请求中,字符串处理可能...
- 可以通过设定字符集(如大小写字母和数字)来决定生成字符串的组成。 - 为了增加安全性,字符串可以包含特殊字符,并且可以设定字符串的唯一性,避免重复。 2. **绘制验证码图像**: - JSP中可以利用`Graphics...
6. **配置Web.config文件**: 需要在Web.config文件中设置正确的连接字符串和其他配置选项,以确保应用可以正确地连接到数据库。 7. **部署页面**: 创建或修改默认的部署页面(如`TestPage.aspx`),并确保页面能够...
2. **Charset**:字符串类型,指定邮件使用的字符集,如“UTF-8”、“GBK”等。 3. **ContentTransferEncoding**:字符串类型,指定邮件正文的编码方式,常见的有“base64”、“quoted-printable”等。 4. **...