contentprovider_provider

本文深入探讨了Android中ContentProvider的实现方式,包括MainActivity的启动、MyContentProvider的具体操作如增删查改,以及MySQliteopenHelper的使用来创建和管理数据库。通过具体的代码示例,读者可以了解到如何在Android应用中正确地使用ContentProvider进行数据共享。

MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

MyContentProvider

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.support.annotation.Nullable;

/**
 * @author alice
 * @version 1.0
 * @Date 2017/10/18 11:19
 */
public class MyContentProvider extends ContentProvider {
    String path = "content://alice.bw.com.contentprovider_provider/student";
    SQLiteDatabase db;
    @Override
    public boolean onCreate() {
        MySQliteopenHelper openher = new MySQliteopenHelper(getContext());
         db = openher.getReadableDatabase();
        return false;
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) {
        Cursor c = db.query("student",strings,s,strings1,null,null,s1);
        return c;
    }

    @Nullable
    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues contentValues) {
        long insert = db.insert("student", null, contentValues);
        Uri u = ContentUris.withAppendedId(Uri.parse(path),insert);
        return u;
    }

    @Override
    public int delete(Uri uri, String s, String[] strings) {
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
        return 0;
    }
}

MySQliteopenHelper

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * @author alice
 * @version 1.0
 * @Date 2017/10/18 11:12
 */
public class MySQliteopenHelper extends SQLiteOpenHelper {

    public MySQliteopenHelper(Context context) {
        super(context, "student", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL("create  table  student(_id integer primary key autoincrement,name text,age text)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
}

main布局

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="alice.bw.com.contentprovider_provider.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"/>
</RelativeLayout>

权限

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="alice.bw.com.day16contentprovidermedia">
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>
在使用 `httplib::Response::set_content_provider` 时,出现参数类型不匹配的错误通常是由于传递的函数对象签名与预期不符。`set_content_provider` 的定义如下: ```cpp void set_content_provider( ContentProvider provider, const std::string& content_type = "text/plain", const std::function<void()>& on_error = nullptr); ``` 其中 `ContentProvider` 是一个接受 `size_t offset`, `size_t length`, 和 `httplib::DataSink &sink` 参数,并返回 `bool` 类型的函数对象[^1]。 ### Lambda 表达式参数顺序和返回类型 在调用 `set_content_provider` 时,若传入的 lambda 表达式参数顺序或返回类型不正确,会导致编译器无法匹配重载函数。例如以下代码片段: ```cpp res.set_content_provider( [](size_t offset, size_t length, httplib::DataSink &sink) -> bool { // 实现内容写入逻辑 return true; }, "application/octet-stream" ); ``` 该 lambda 明确指定了 `(offset, length, sink)` 的参数顺序,并返回 `bool` 类型,完全符合 `ContentProvider` 的要求。如果误将参数顺序颠倒,或未指定返回类型,则会导致模板推导失败。 ### 对象类型匹配问题 另一个常见问题是 `set_content_provider` 被调用的对象类型不正确。确保调用的是 `httplib::Response` 类型的实例。例如: ```cpp httplib::Response res; res.set_content_provider(provider, "application/octet-stream"); ``` 若对象不是 `httplib::Response` 类型,或未正确初始化,则可能引发编译错误或运行时异常。 ### 内容提供者的实现建议 为了提高性能并避免内存泄漏,在实现 `ContentProvider` 时应采用缓冲机制分块读取文件。例如: ```cpp res.set_content_provider( [file_path](size_t offset, size_t length, httplib::DataSink &sink) -> bool { FILE* fp = fopen(file_path.c_str(), "rb"); if (!fp) return false; fseek(fp, static_cast<long>(offset), SEEK_SET); char buf[1024]; while (length > 0) { auto read_len = fread(buf, 1, std::min(sizeof(buf), length), fp); if (read_len <= 0) break; if (!sink.write(buf, read_len)) { fclose(fp); return false; } length -= read_len; } fclose(fp); return true; }, "application/octet-stream" ); ``` 该实现中使用了固定大小的缓冲区进行分块读取,避免一次性加载整个文件到内存,从而减少内存占用并提高 I/O 效率。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值