【问题标题】:Android studio getting skipping frames error and application not responding dialogAndroid Studio 出现跳帧错误和应用程序无响应对话框
【发布时间】:2018-10-02 10:15:19
【问题描述】:

我是 android studio(Android 应用开发)的新手。

在开发 Android 应用程序时遇到问题。出现以下错误

"Skipped 3 frames! The application may be doing too much work on its main thread."

并显示对话框"application not responding"

我正在使用 sqlite 数据库创建/写入 xml 文件到外部存储。

请帮助我如何解决这个问题?

DbHelper.java

package com.techyour.bank;

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

import java.util.ArrayList;
import java.util.List;

public class DbHelper extends SQLiteOpenHelper {
    private SQLiteDatabase db;

    public static final String DB_NAME = "my_bank_data.db";
    private static final int DB_VERSION = 1;
    public static final String TABLE_NAME = "my_banks";

    public static final String _ID = "_id";
    public static final String NAME = "name";
    public static final String AGE = "age";
    public static final String GENDER = "gender";
    public static final String DOB = "dob";
    public static final String COUNTRY = "country";
    public static final String PH_NO = "ph_no";


    public DbHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        this.db = db;

        final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME +
                " ( " +
                _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                NAME + " TEXT, " +
                AGE + " TEXT, " +
                GENDER + " TEXT, " +
                DOB + " TEXT, " +
                COUNTRY + " TEXT, " +
                PH_NO + " TEXT " +
                ")";

        db.execSQL(CREATE_TABLE);
        defaultData();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }

    private void defaultData() {
        GetSet a1 = new GetSet("Alice", "20", "Male", "1994", "USA", "9876543210");
        defaultData2(a1);
        GetSet a2 = new GetSet("Bob", "21", "Male", "1997", "UK", "4002639610");
        defaultData2(a2);
        GetSet a3 = new GetSet("Eve", "22", "Male", "1964", "INDIA", "7040576498");
        defaultData2(a3);
        GetSet a4 = new GetSet("Mildred Martin", "23", "Male", "1959", "USA", "2113309849");
        defaultData2(a4);
        GetSet a5 = new GetSet("Ruth    Hill", "24", "Male", "1918", "USA", "6296713680");
        defaultData2(a5);
        GetSet a6 = new GetSet("Justin  Baker", "25", "Male", "1976", "USA", "5113788645");
        defaultData2(a6);
        GetSet a7 = new GetSet("Carl    Coleman", "26", "Male", "1945", "USA", "9346135599");
        defaultData2(a7);
        GetSet a8 = new GetSet("Wanda   Mitchell", "27", "Male", "1909", "USA", "9134105633");
        defaultData2(a8);
        GetSet a9 = new GetSet("Joe Bennett", "28", "Male", "1915", "UK", "6383446319");
        defaultData2(a9);
        GetSet a10 = new GetSet("Willie Carter", "29", "Male", "1958", "USA", "5578230822");
        defaultData2(a10);
        GetSet a11 = new GetSet("Debra  Bryant", "21", "Male", "1980", "USA", "4818754159");
        defaultData2(a11);
        GetSet a12 = new GetSet("Christopher    Powell", "20", "Male", "1913", "USA", "0403170292");
        defaultData2(a12);
        GetSet a13 = new GetSet("Gloria Moore", "30", "Male", "1947", "USA", "5206569101");
        defaultData2(a13);
        GetSet a14 = new GetSet("Beverly    Nelson", "20", "Male", "1905", "UK", "9449903813");
        defaultData2(a14);
        GetSet a15 = new GetSet("Melissa    Davis", "22", "Female", "1955", "USA", "5961002003");
        defaultData2(a15);
        GetSet a16 = new GetSet("Janet  Price", "17", "Male", "1935", "USA", "1977492463");
        defaultData2(a16);
        GetSet a17 = new GetSet("Helen  Edwards", "20", "Male", "1910", "USA", "6834805918");
        defaultData2(a17);
        GetSet a18 = new GetSet("Craig  Garcia", "23", "Male", "1911", "INDIA", "0807332318");
        defaultData2(a18);
        GetSet a19 = new GetSet("Deborah    Jenkins", "20", "Male", "1935", "USA", "0068416390");
        defaultData2(a19);
        GetSet a20 = new GetSet("Tina   Stewart", "20", "Female", "1963", "USA", "1054983413");
        defaultData2(a20);
        GetSet a21 = new GetSet("Kimberly   Howard", "31", "Male", "1911", "USA", "9852591520");
        defaultData2(a21);
        GetSet a22 = new GetSet("Earl   Bailey", "20", "Male", "1948", "USA", "9546632144");
        defaultData2(a22);
        GetSet a23 = new GetSet("Wayne  Hernandez", "28", "Female", "1900", "INDIA", "9837178563");
        defaultData2(a23);
        GetSet a24 = new GetSet("Terry  Cook", "18", "Male", "1910", "USA", "8298923456");
        defaultData2(a24);
        GetSet a25 = new GetSet("Ronald Evans", "20", "Male", "1994", "USA", "4541427090");
        defaultData2(a25);
        GetSet a26 = new GetSet("Doris  Brooks", "20", "Male", "1958", "INDIA", "0960421257");
        defaultData2(a26);
        GetSet a27 = new GetSet("Sarah  Simmons", "19", "Female", "1982", "USA", "5305824976");
        defaultData2(a27);
        GetSet a28 = new GetSet("Frank  Thompson", "26", "Male", "1973", "USA", "9079724716");
        defaultData2(a28);
        GetSet a29 = new GetSet("Smith", "20", "Male", "1954", "USA", "6300051365");
        defaultData2(a29);
        GetSet a30 = new GetSet("Jhon", "27", "Male", "1989", "UK", "4545983296");
        defaultData2(a30);
    }

    private void defaultData2(GetSet getSet) {
        ContentValues cv = new ContentValues();
        cv.put(NAME, getSet.getNAME());
        cv.put(AGE, getSet.getAGE());
        cv.put(GENDER, getSet.getGENDER());
        cv.put(DOB, getSet.getDOB());
        cv.put(COUNTRY, getSet.getCOUNTRY());
        cv.put(PH_NO, getSet.getPH_NO());
        db.insert(TABLE_NAME, null, cv);
    }

    public List<GetSet> getAllData(String where) {
        List<GetSet> list = new ArrayList<>();
        db = getReadableDatabase();

        String[] selectionArgs = new String[]{where};
        Cursor c = db.rawQuery("SELECT * FROM " + TABLE_NAME +
                " WHERE " + _ID + " = ?", selectionArgs);

        if (c.moveToFirst()) {
            do {
                GetSet getSet = new GetSet();
                getSet.setNAME(c.getString(c.getColumnIndex(NAME)));
                getSet.setAGE(c.getString(c.getColumnIndex(AGE)));
                getSet.setGENDER(c.getString(c.getColumnIndex(GENDER)));
                getSet.setDOB(c.getString(c.getColumnIndex(DOB)));
                getSet.setCOUNTRY(c.getString(c.getColumnIndex(COUNTRY)));
                getSet.setPH_NO(c.getString(c.getColumnIndex(PH_NO)));
                list.add(getSet);
            } while (c.moveToNext());
        }

        c.close();
        return list;
    }

    public List<GetSet> getDataCount() {
        List<GetSet> list2 = new ArrayList<>();
        db = getReadableDatabase();

        Cursor c = db.rawQuery("SELECT * FROM " + TABLE_NAME +
                " WHERE " + NAME + " IS NOT NULL ", null);

        if (c.moveToFirst()) {
            do {
                GetSet getSet = new GetSet();
                getSet.setNAME(c.getString(c.getColumnIndex(NAME)));
                list2.add(getSet);
            } while (c.moveToNext());
        }

        c.close();
        return list2;
    }

    public Cursor getDataById(String id) {
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME +
                " WHERE " + _ID + " = ?", new String[]{id});
        return cursor;
    }
}

MainActivity.java

package com.techyour.bank;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Xml;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import org.xmlpull.v1.XmlSerializer;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    TextView tvData;

    DbHelper dbHelper;
    GetSet getSet;
    List<GetSet> dataList;

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

        dbHelper = new DbHelper(this);
        dbHelper.getWritableDatabase();

        tvData = findViewById(R.id.tvData);

        checkPermission();
    }

    private void checkPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }
    }

    public void ocBtnGetSet(View view) throws IOException {
        XmlSerializer xmlSerializer = Xml.newSerializer();
        StringWriter writer = new StringWriter();

        try {
            xmlSerializer.setOutput(writer);
            xmlSerializer.startDocument("UTF-8", true);
            xmlSerializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
            xmlSerializer.startTag("", "persons");
        } catch (IOException e) {
            e.printStackTrace();
        }

        for (int i = 1; i <= dbHelper.getDataCount().size(); i++) {
            dataList = dbHelper.getAllData(String.valueOf(i));
            getSet = dataList.get(0);

            try {
                xmlSerializer.startTag("", "person");

                xmlSerializer.startTag("", "name");
                xmlSerializer.text(getSet.getNAME());
                xmlSerializer.endTag("", "name");

                xmlSerializer.startTag("", "age");
                xmlSerializer.text(getSet.getAGE());
                xmlSerializer.endTag("", "age");

                xmlSerializer.startTag("", "gender");
                xmlSerializer.text(getSet.getGENDER());
                xmlSerializer.endTag("", "gender");

                xmlSerializer.startTag("", "dob");
                xmlSerializer.text(getSet.getDOB());
                xmlSerializer.endTag("", "dob");

                xmlSerializer.startTag("", "country");
                xmlSerializer.text(getSet.getCOUNTRY());
                xmlSerializer.endTag("", "country");

                xmlSerializer.startTag("", "ph_no");
                xmlSerializer.text(getSet.getPH_NO());
                xmlSerializer.endTag("", "ph_no");

                xmlSerializer.endTag("", "person");

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        xmlSerializer.endTag("", "persons");
        xmlSerializer.endDocument();

        tvData.append(writer.toString());

        writeXmlToSd(writer.toString());
    }

    private void writeXmlToSd(String data) {
        String state = Environment.getExternalStorageState();

        if (Environment.MEDIA_MOUNTED.equals(state)) {
            File Root = Environment.getExternalStorageDirectory();
            File Dir = new File(Root.getAbsolutePath() + "/AABBCC");

            if (!Dir.exists()) {
                Dir.mkdir();
            }

            File file = new File(Dir, "backup.xml");

            String text = data;

            try {
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(text.getBytes());
                fos.close();

                Toast.makeText(this, "Backup Success", Toast.LENGTH_SHORT).show();

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(this, "SD Card Not Found", Toast.LENGTH_SHORT).show();
        }
    }
}

GetSet.java

package com.techyour.bank;

/**
 * Created by Vamshi Krishna on 01-10-2018 001.
 */

class GetSet {
    private String NAME;
    private String AGE;
    private String GENDER;
    private String DOB;
    private String COUNTRY;
    private String PH_NO;

    GetSet() {
    }

    public GetSet(String NAME, String AGE, String GENDER, String DOB, String COUNTRY, String PH_NO) {
        this.NAME = NAME;
        this.AGE = AGE;
        this.GENDER = GENDER;
        this.DOB = DOB;
        this.COUNTRY = COUNTRY;
        this.PH_NO = PH_NO;
    }

    public String getNAME() {
        return NAME;
    }

    public void setNAME(String NAME) {
        this.NAME = NAME;
    }

    public String getAGE() {
        return AGE;
    }

    public void setAGE(String AGE) {
        this.AGE = AGE;
    }

    public String getGENDER() {
        return GENDER;
    }

    public void setGENDER(String GENDER) {
        this.GENDER = GENDER;
    }

    public String getDOB() {
        return DOB;
    }

    public void setDOB(String DOB) {
        this.DOB = DOB;
    }

    public String getCOUNTRY() {
        return COUNTRY;
    }

    public void setCOUNTRY(String COUNTRY) {
        this.COUNTRY = COUNTRY;
    }

    public String getPH_NO() {
        return PH_NO;
    }

    public void setPH_NO(String PH_NO) {
        this.PH_NO = PH_NO;
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="6dp"
    tools:context="com.techyour.bank.MainActivity">

    <Button
        android:id="@+id/btnGetSet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="ocBtnGetSet"
        android:text="Get" />

    <ScrollView
        android:id="@+id/sv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/btnGetSet">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tvData"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="20sp" />

        </LinearLayout>
    </ScrollView>
</RelativeLayout>

代码已更新(MainActivity.java)但出现同样的错误

package com.techyour.bank;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Xml;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import org.xmlpull.v1.XmlSerializer;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    DbHelper dbHelper;
    GetSet getSet;
    List<GetSet> dataList;

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

        dbHelper = new DbHelper(this);
        dbHelper.getWritableDatabase();

        checkPermission();
    }

    private void checkPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }
    }

    public void ocBtnGetSet(View view) throws IOException {
        new MyTask().execute();
    }

    private void writeXmlToSd(String data) {
        String state = Environment.getExternalStorageState();

        if (Environment.MEDIA_MOUNTED.equals(state)) {
            File Root = Environment.getExternalStorageDirectory();
            File Dir = new File(Root.getAbsolutePath() + "/AABBCC");

            if (!Dir.exists()) {
                Dir.mkdir();
            }

            File file = new File(Dir, "backup.xml");

            String text = data;

            try {
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(text.getBytes());
                fos.close();

                Toast.makeText(this, "Backup Success", Toast.LENGTH_SHORT).show();

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            Toast.makeText(this, "SD Card Not Found", Toast.LENGTH_SHORT).show();
        }
    }


    private class MyTask extends AsyncTask<Void, Void, String> {
        TextView tvData;

        @Override
        protected String doInBackground(Void... voids) {
            tvData = findViewById(R.id.tvData);

            XmlSerializer xmlSerializer = Xml.newSerializer();
            StringWriter writer = new StringWriter();

            try {
                xmlSerializer.setOutput(writer);
                xmlSerializer.startDocument("UTF-8", true);
                xmlSerializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
                xmlSerializer.startTag("", "persons");
            } catch (IOException e) {
                e.printStackTrace();
            }

            for (int i = 1; i <= dbHelper.getDataCount().size(); i++) {
                dataList = dbHelper.getAllData(String.valueOf(i));
                getSet = dataList.get(0);

                try {
                    xmlSerializer.startTag("", "person");

                    xmlSerializer.startTag("", "name");
                    xmlSerializer.text(getSet.getNAME());
                    xmlSerializer.endTag("", "name");

                    xmlSerializer.startTag("", "age");
                    xmlSerializer.text(getSet.getAGE());
                    xmlSerializer.endTag("", "age");

                    xmlSerializer.startTag("", "gender");
                    xmlSerializer.text(getSet.getGENDER());
                    xmlSerializer.endTag("", "gender");

                    xmlSerializer.startTag("", "dob");
                    xmlSerializer.text(getSet.getDOB());
                    xmlSerializer.endTag("", "dob");

                    xmlSerializer.startTag("", "country");
                    xmlSerializer.text(getSet.getCOUNTRY());
                    xmlSerializer.endTag("", "country");

                    xmlSerializer.startTag("", "ph_no");
                    xmlSerializer.text(getSet.getPH_NO());
                    xmlSerializer.endTag("", "ph_no");

                    xmlSerializer.endTag("", "person");

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            try {
                xmlSerializer.endTag("", "persons");
                xmlSerializer.endDocument();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return writer.toString();
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String aVoid) {
            tvData.setText(aVoid);
            writeXmlToSd(aVoid);
            Toast.makeText(MainActivity.this, "SUCCESS", Toast.LENGTH_SHORT).show();
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }
    }

}

【问题讨论】:

  • 在后台线程或AsyncTask中使用文件写入进程。
  • 我不知道如何使用线程和异步任务。你能解释一下吗?

标签: android xml android-asynctask android-sqlite android-studio-3.0


【解决方案1】:

您实际上在主线程中做了很多工作。主线程运行应用程序的所有用户界面工作。 考虑在单独的线程中运行您的数据库代码。

您可以在https://developer.android.com/guide/components/processes-and-threadshttps://developer.android.com/guide/components/processes-and-threads 处的开发者文档中找到有关线程的更多信息

如果您将该工作卸载到线程,请确保您的 UI 告诉您的用户后台有正在进行的工作,以便用户不会放弃屏幕。

【讨论】:

    【解决方案2】:

    将所有繁重的工作转移到 AsyncTask

    使 AsyncTask 像,

    class MyTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... voids) {
            XmlSerializer xmlSerializer = Xml.newSerializer();
            StringWriter writer = new StringWriter();
    
            try {
                xmlSerializer.setOutput(writer);
                xmlSerializer.startDocument("UTF-8", true);
                xmlSerializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
                xmlSerializer.startTag("", "persons");
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            for (int i = 1; i <= dbHelper.getDataCount().size(); i++) {
                dataList = dbHelper.getAllData(String.valueOf(i));
                getSet = dataList.get(0);
    
                try {
                    xmlSerializer.startTag("", "person");
    
                    xmlSerializer.startTag("", "name");
                    xmlSerializer.text(getSet.getNAME());
                    xmlSerializer.endTag("", "name");
    
                    xmlSerializer.startTag("", "age");
                    xmlSerializer.text(getSet.getAGE());
                    xmlSerializer.endTag("", "age");
    
                    xmlSerializer.startTag("", "gender");
                    xmlSerializer.text(getSet.getGENDER());
                    xmlSerializer.endTag("", "gender");
    
                    xmlSerializer.startTag("", "dob");
                    xmlSerializer.text(getSet.getDOB());
                    xmlSerializer.endTag("", "dob");
    
                    xmlSerializer.startTag("", "country");
                    xmlSerializer.text(getSet.getCOUNTRY());
                    xmlSerializer.endTag("", "country");
    
                    xmlSerializer.startTag("", "ph_no");
                    xmlSerializer.text(getSet.getPH_NO());
                    xmlSerializer.endTag("", "ph_no");
    
                    xmlSerializer.endTag("", "person");
    
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            xmlSerializer.endTag("", "persons");
            xmlSerializer.endDocument();
    
            tvData.append(writer.toString());
    
            writeXmlToSd(writer.toString());
            return null;
        }
    }
    

    然后通过调用在click函数中执行任务

    new MyTask().execute();
    

    【讨论】:

    • 感谢您的帮助
    • 在实现您的代码后,我仍然遇到同样的错误。
    • 为什么要在后台分配 textview 的 id ?删除它。
    • 只是跳帧或无响应对话框的日志?
    • 两者,在日志中显示跳帧,点击链接按钮时在手机中显示无响应。
    【解决方案3】:
     <Button
            android:id="@+id/btnGetSet"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="ocBtnGetSet"
            android:text="Get" />
    

    ocBtnGetSet

    上面的这个函数有问题。因为在这个函数中你正在做数据库操作。

    您正在主线程上执行繁重的操作。基本上是一个主线程上的 android 应用程序。如果您想要像数据库这样的繁重操作或调用 API 来获取数据。您可以使用AsyncTask。它与主线程分开运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      • 2016-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多