使用片段状态寻呼机适配器和 SQLite 数据库中的数据实现 swipe 接口时崩溃

Posted

技术标签:

【中文标题】使用片段状态寻呼机适配器和 SQLite 数据库中的数据实现 swipe 接口时崩溃【英文标题】:Crash during implementation of swipe interface using fragment state pager adapter with data from SQLite database 【发布时间】:2017-12-13 18:41:04 【问题描述】:

我正在尝试实现一个滑动界面来滑动包含书籍列表的数据库。由于它来自数据库,因此我使用了 FragmentStatePagerAdapter。该代码显示没有编译错误,但是一旦我多次滑动,应用程序就会崩溃 代码:

public class swipeActivity extends AppCompatActivity 
//static int num_items;

bookAdapter mAdapter;
ViewPager mPager;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_swipe);

    mAdapter = new bookAdapter(getSupportFragmentManager(), this);
    mPager = (ViewPager) findViewById(R.id.pager);
    mPager.setAdapter(mAdapter);




public static class bookAdapter extends FragmentStatePagerAdapter 
    private Context context;

    public bookAdapter(FragmentManager fm, Context c) 
        super(fm);
        context = c;
    

    @Override
    public int getCount() 
        DBHandler db = new DBHandler(context);
        return db.getBookCount();
    

    @Override
    public Fragment getItem(int position) 

        return ArrayListFragment.newInstance(position);
    



public static class ArrayListFragment extends ListFragment 
    int mNum;
    private Cursor cursor;

    //ListView bookList;
    static ArrayListFragment newInstance(int num) 
        ArrayListFragment f = new ArrayListFragment();
        Bundle args = new Bundle();
        args.putInt("num", num);
        f.setArguments(args);

        return f;
    

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        mNum = getArguments() != null ? getArguments().getInt("num") : 1;
        DBHandler db = new DBHandler(getContext());
        cursor = db.getCursor();

    

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 

        cursor.moveToPosition(mNum);
        View v = inflater.inflate(R.layout.fragment_swipe, container, false);
        View tv = v.findViewById(R.id.textTitle);
        ((TextView) tv).setText(cursor.getString(1));
        tv = v.findViewById(R.id.textAuth);
        ((TextView) tv).setText(cursor.getString(2));
        tv = v.findViewById(R.id.textNos);
        ((TextView) tv).setText("Copies : " + cursor.getString(4));
        cursor.close();

        return v;
    

    @Override
    public void onActivityCreated(Bundle savedInstanceState) 
        super.onActivityCreated(savedInstanceState);
        /* stuff*/

    

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) 
        Log.i("FragmentList", "Item clicked: " + id);
    


错误日志:

07-10 11:39:09.758 4081-4081/com.example.ajay_5674.library1 E/SQLiteLog: (14) 无法在 [bda77dda96] 的第 32456 行打开文件

07-10 11:39:09.758 4081-4081/com.example.ajay_5674.library1 E/SQLiteLog: (14) os_unix.c:32456: (24) open(/data/user/0/com.example .ajay_5674.library1/databases/libraryInfo1-journal) - 07-10 11:39:09.758 4081-4081/com.example.ajay_5674.library1 E/SQLiteLog: (14) 无法在 [bda77dda96] 的第 32456 行打开文件

07-10 11:39:09.758 4081-4081/com.example.ajay_5674.library1 E/SQLiteLog: (14) os_unix.c:32456: (24) open(/data/user/0/com.example .ajay_5674.library1/databases/libraryInfo1-journal) -

07-10 11:39:09.758 4081-4081/com.example.ajay_5674.library1 E/SQLiteLog:(14) 语句在 12 处中止:[SELECT * FROM library] 无法打开数据库文件 07-10 11:39:09.759 4081-4081/com.example.ajay_5674.library1 E/SQLiteQuery:异常:无法打开数据库文件(代码 14);查询:SELECT * FROM library

07-10 11:39:09.759 4081-4081/com.example.ajay_5674.library1 D/androidRuntime:关闭虚拟机

07-10 11:39:09.759 4081-4081/com.example.ajay_5674.library1 E/AndroidRuntime: FATAL EXCEPTION: main

进程:com.example.ajay_5674.library1,PID:4081 android.database.sqlite.SQLiteCantOpenDatabaseException: 无法打开数据库文件(代码 14)

编辑:发现问题。我专注于片段创建期间的查询,我在项目计数期间没有注意到查询!固定为:

public static class bookAdapter extends FragmentStatePagerAdapter 
    private Context context;
    int num_items;
    public bookAdapter(FragmentManager fm, Context c) 
        super(fm);
        context = c;
        DBHandler db = new DBHandler(context);
        num_items = db.getBookCount();
        db.close();
    

    @Override
    public int getCount() 

        //Log.d("Book Count :",Integer.toString(db.getBookCount()));
        return num_items;
    

    @Override
    public Fragment getItem(int position) 

        Log.d("Book Position :",Integer.toString(position));
        return ArrayListFragment.newInstance(position);

    


【问题讨论】:

***.com/questions/35008632/… @IntelliJAmiya 我添加了一个 db.close() 但它没有帮助。 我的应用不需要任何查询即可跳过 【参考方案1】:

实际问题是android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14),这是因为您正在创建 SQLite 数据库的多个实例。

您每次都在需要时创建一个 DBHandler。尝试减少 DBHandler 的实例。

你也在 onCreateView 中关闭光标并在 onCreate() 中创建它。这不是一个好习惯。如果您在 onCreate 中打开光标,则应在 onDestory() 中将其关闭。

【讨论】:

如果您仍然遇到问题,请同时发布 DBHandler 代码。 谢谢,我已经做了 onDestroy 的事情,忘了提。但解决了问题。大量的数据库查询来自我的 getCount() 方法。所以我修复了它

以上是关于使用片段状态寻呼机适配器和 SQLite 数据库中的数据实现 swipe 接口时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

将活动回调发送到片段

需要从寻呼机适配器识别当前视图片段

从活动更新视图页面中片段中的列表视图

使用 viewpager 创建多个片段

如何将SQLite数据与可重用的RecyclerView适配器一起使用

如何在回收站视图中的每个项目下方创建寻呼机指示器