应用程序启动时出现白屏

App starts with white screen

我制作了一个从 url 加载图像并使用 CarouselWidget

在 coverflow 视图中显示它们的应用程序

Click to view the sample

  1. 当我 运行 我的应用程序第一次在 Genymotion 中时,它会下载数据库,从查询中获得结果,但不会构建 coverflow。当我 运行 第二次时,它会构建视图。为什么它不是第一次构建它?我在 onPostExecute 方法中包含了 coverflow 构建。

  2. 当我在真实设备上 运行 时,我总是看到白屏。当我 运行 它在设备上处于调试模式并确实退出时,它 运行 没问题。如果我没有收到任何错误,我该如何在设备上调试它?

  3. 如何动态加载图像?不是同时,而是在滑动的过程中。

这是我的代码。

    public class MainActivity extends AppCompatActivity {

    private static final String TAG = "qwe";
    public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
    private static final String DB1_NAME = "SuperupDB.sqlite";
    private static final String DB2_NAME = "InventoryDB.sqlite";
    private static final String DB_URL = "https://storage.googleapis.com/shared_data/MKGn299XpJ6mn9c6/clientsync/db/SuperupDB.zip";
    private String dbQuery;
    private ProgressDialog mProgressDialog;

    private static String DB_PATH;

    private CoverFlowAdapter mAdapter;
    private ArrayList<Bitmap> mData = new ArrayList<>();

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

        if (android.os.Build.VERSION.SDK_INT >= 17) {
            DB_PATH = this.getApplicationInfo().dataDir + "/databases/";
        } else {
            DB_PATH = "/data/data/" + this.getPackageName() + "/databases/";
        }

        File dbFile1 = new File(DB_PATH + DB1_NAME);
        File dbFile2 = new File(DB_PATH + DB2_NAME);
        Log.d(TAG, dbFile1.getPath() + " " + dbFile1.exists());
        Log.d(TAG, dbFile2.getPath() + " " + dbFile2.exists());

        dbQuery = "Select p.PrdImgURL, cp.PrdID " +
                "from Products as p " +
                "inner join CategoryProduct_MM as cp " +
                "on p.PrdID = cp.PrdID " +
                "inner join InventoryDB.Facing as f " +
                "on p.PrdID = f.PrdID " +
                "where cp.CategoryID == 1 " +
                "and p.PrdImgURL is not null " +
                "order by f.`Order`";

        if (dbFile1.exists() && dbFile2.exists()) {
            loadProducts();
        } else {
            new DownloadDB().execute(DB_URL);
        }


    }

    private void loadProducts() {
        dbHandler dbh = dbHandler.getInstance(this);
        SQLiteDatabase db = dbh.getWritableDatabase();
        // attach second db to get products order from it
        db.execSQL("attach database ? as InventoryDB", new String[]{DB_PATH + DB2_NAME});
        db.beginTransaction();

        Cursor c = db.rawQuery(dbQuery, null);
        int count = c.getCount();
        String url[] = new String[count];
        int i = 0;


        while (c.moveToNext()) {
            url[i] = c.getString(c.getColumnIndex("PrdImgURL"));
            i++;
        }

        for (i = 0; i < url.length; i++) {
            loadBitmap(url[i]);
            Log.d(TAG, url[i]);
        }

        mAdapter = new CoverFlowAdapter(getApplicationContext());
        mAdapter.setData(mData);
        CoverFlowCarousel mCoverFlow = (CoverFlowCarousel) findViewById(R.id.coverflow);
        mCoverFlow.setAdapter(mAdapter);
    }

    private void loadBitmap(final String url) {
        RequestQueue queue = Volley.newRequestQueue(this);
        ImageRequest imageRequest = new ImageRequest(url,
                new Response.Listener<Bitmap>() {
                    @Override
                    public void onResponse(Bitmap bitmap) {
                        //mData.add(bitmap);
                        mData.add(addShadow(bitmap, bitmap.getHeight(), bitmap.getWidth(), Color.BLACK, 7, 3, 7));
                    }
                }, 0, 0, null,
                new Response.ErrorListener() {
                    public void onErrorResponse(VolleyError error) {
                        Log.d(TAG, "loadBitmap: " + error.toString());
                    }
                });
        queue.add(imageRequest);
    }

    public Bitmap addShadow(final Bitmap bm, final int dstHeight, final int dstWidth, int color, int size, float dx, float dy) {
        final Bitmap mask = Bitmap.createBitmap(dstWidth, dstHeight, Bitmap.Config.ALPHA_8);

        final Matrix scaleToFit = new Matrix();
        final RectF src = new RectF(0, 0, bm.getWidth(), bm.getHeight());
        final RectF dst = new RectF(0, 0, dstWidth - dx, dstHeight - dy);
        scaleToFit.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);

        final Matrix dropShadow = new Matrix(scaleToFit);
        dropShadow.postTranslate(dx, dy);

        final Canvas maskCanvas = new Canvas(mask);
        final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        maskCanvas.drawBitmap(bm, scaleToFit, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
        maskCanvas.drawBitmap(bm, dropShadow, paint);

        final BlurMaskFilter filter = new BlurMaskFilter(size, BlurMaskFilter.Blur.NORMAL);
        paint.reset();
        paint.setAntiAlias(true);
        paint.setColor(color);
        paint.setMaskFilter(filter);
        paint.setFilterBitmap(true);

        final Bitmap ret = Bitmap.createBitmap(dstWidth + size, dstHeight + size, Bitmap.Config.ARGB_8888);
        final Canvas retCanvas = new Canvas(ret);
        retCanvas.drawBitmap(mask, 0, 0, paint);
        retCanvas.drawBitmap(bm, scaleToFit, null);
        mask.recycle();
        return ret;
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case DIALOG_DOWNLOAD_PROGRESS:
                mProgressDialog = new ProgressDialog(this);
                mProgressDialog.setMessage("Loading database..");
                mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                mProgressDialog.setCancelable(false);
                mProgressDialog.show();
                return mProgressDialog;
            default:
                return null;
        }
    }

    class DownloadDB extends AsyncTask<String, String, String> {

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

        @Override
        protected String doInBackground(String... aurl) {
            int count;

            try {

                URL url = new URL(aurl[0]);
                URLConnection conn = url.openConnection();
                conn.connect();

                long lengthOfFile = conn.getContentLength();
                Log.d(TAG, "Length of file: " + lengthOfFile);

                InputStream input = new BufferedInputStream(url.openStream());
                ZipInputStream zis = new ZipInputStream(input);

                //default database directory
                File dbDir = new File(DB_PATH);
                if (!dbDir.exists())
                    dbDir.mkdir();

                try {
                    ZipEntry ze;
                    while ((ze = zis.getNextEntry()) != null) {
                        if (ze.getName().equals(DB1_NAME) || ze.getName().equals(DB2_NAME)) {
                            lengthOfFile = ze.getSize();
                            FileOutputStream fout = new FileOutputStream(new File(dbDir, ze.getName()));
                            byte[] data = new byte[1024];
                            long total = 0;
                            while ((count = zis.read(data)) != -1) {
                                total += count;
                                publishProgress("" + (int) ((total * 100) / lengthOfFile));
                                fout.write(data, 0, count);
                            }
                            zis.closeEntry();
                            fout.close();
                        }
                    }
                } catch (Exception e) {
                    Log.d(TAG, e.toString());
                } finally {
                    zis.close();
                }

            } catch (Exception e) {
                Log.d(TAG, e.toString());
            }
            return null;

        }

        protected void onProgressUpdate(String... progress) {
            Log.d(TAG, progress[0]);
            mProgressDialog.setProgress(Integer.parseInt(progress[0]));
        }

        @Override
        protected void onPostExecute(String unused) {
            dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
            loadProducts();
        }
    }
}


    public class dbHandler extends SQLiteOpenHelper {
    private static final int VERSION = 1;
    private static final String DATABASE_NAME = "SuperupDB.sqlite";
    private static final String TAG = "qwe";
    private static File DATABASE_FILE;

    // This is an indicator if we need to copy the
    // database file.
    private boolean mInvalidDatabaseFile = false;
    private boolean mIsUpgraded = false;
    private Context mContext;

    /**
     * number of users of the database connection.
     */
    private int mOpenConnections = 0;

    private static dbHandler mInstance;

    synchronized static public dbHandler getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new dbHandler(context.getApplicationContext());
        }
        return mInstance;
    }

    private dbHandler(Context context) {
        super(context, DATABASE_NAME, null, VERSION);
        this.mContext = context;
        SQLiteDatabase db = null;
        try {
            db = getReadableDatabase();
            if (db != null) {
                db.close();
            }

            DATABASE_FILE = context.getDatabasePath(DATABASE_NAME);

/*            if (mInvalidDatabaseFile) {
                //copyDatabase();
                Log.d(TAG, "Where is db?");
            }*/
            if (mIsUpgraded) {
                doUpgrade();
            }
        } catch (SQLiteException e) {
        } finally {
            if (db != null && db.isOpen()) {
                db.close();
            }
        }
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //mInvalidDatabaseFile = true;

    }

    @Override
    public void onUpgrade(SQLiteDatabase database,
                          int old_version, int new_version) {
        //mInvalidDatabaseFile = true;
        mIsUpgraded = true;

    }

    /**
     * called if a database upgrade is needed
     */
    private void doUpgrade() {
        // implement the database upgrade here.
    }

    @Override
    public synchronized void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
        // increment the number of users of the database connection.
        mOpenConnections++;
        if (!db.isReadOnly()) {
            // Enable foreign key constraints
            db.execSQL("PRAGMA foreign_keys=ON;");
        }
    }

    /**
     * implementation to avoid closing the database connection while it is in
     * use by others.
     */
    @Override
    public synchronized void close() {
        mOpenConnections--;
        if (mOpenConnections == 0) {
            super.close();
        }
    }

    private void setDatabaseVersion() {
        SQLiteDatabase db = null;
        try {
            db = SQLiteDatabase.openDatabase(DATABASE_FILE.getAbsolutePath(), null,
                    SQLiteDatabase.OPEN_READWRITE);
            db.execSQL("PRAGMA user_version = " + VERSION);
        } catch (SQLiteException e) {
        } finally {
            if (db != null && db.isOpen()) {
                db.close();
            }
        }
    }

}

通过 Universal Image Loader 延迟加载图像解决了这个问题。
Here is the example

另一种解决此问题的方法是在应用的 style.xml 文件中添加以下行:

<item name="android:windowDisablePreview">true</item>