public List<HistoryItem> loadAll() { if (!ctx.getFileStreamPath(HISTORY_FILENAME).exists()) { return null; } ObjectInputStream in = null; try { in = new ObjectInputStream(ctx.openFileInput(HISTORY_FILENAME)); @SuppressWarnings("unchecked") // readObject() return Object. List<HistoryItem> res = (List<HistoryItem>) in.readObject(); return res; } catch (Exception e) { Log.e(TAG, "Unable to deserialize history", e); // delete it as it's likely corrupted ctx.getFileStreamPath(HISTORY_FILENAME).delete(); return null; } finally { if (in != null) { try { in.close(); } catch (IOException e) { Log.e(TAG, "", e); } } } }
/** 根据文件的绝对路径判断文件是否存在 */ public static boolean isExistDataCache(Context cxt, String file) { boolean exist = false; File data = cxt.getFileStreamPath(file); if (data.exists()) exist = true; return exist; }
private static boolean writeKeyToFile(Context context, String basename, SecretKey key) { File file = context.getFileStreamPath(basename); byte[] keyBytes = key.getEncoded(); FileOutputStream output = null; if (MAC_KEY_BYTE_COUNT != keyBytes.length) { Log.e( TAG, "writeKeyToFile got key encoded bytes length " + keyBytes.length + "; expected " + MAC_KEY_BYTE_COUNT); return false; } try { output = new FileOutputStream(file); output.write(keyBytes); return true; } catch (Exception e) { Log.e(TAG, "Could not write key to '" + file + "': " + e); return false; } finally { try { if (output != null) { output.close(); } } catch (IOException e) { Log.e(TAG, "Could not close key output stream '" + file + "': " + e); } } }
private static SecretKey readKeyFromFile(Context context, String basename, String algorithmName) { FileInputStream input = null; File file = context.getFileStreamPath(basename); try { if (file.length() != MAC_KEY_BYTE_COUNT) { Log.w(TAG, "Could not read key from '" + file + "': invalid file contents"); return null; } byte[] keyBytes = new byte[MAC_KEY_BYTE_COUNT]; input = new FileInputStream(file); if (MAC_KEY_BYTE_COUNT != input.read(keyBytes)) { return null; } try { return new SecretKeySpec(keyBytes, algorithmName); } catch (IllegalArgumentException e) { return null; } } catch (Exception e) { Log.w(TAG, "Could not read key from '" + file + "': " + e); return null; } finally { try { if (input != null) { input.close(); } } catch (IOException e) { Log.e(TAG, "Could not close key input stream '" + file + "': " + e); } } }
/** * Attempts to unpack a grammar resource into cache. The unpacked copy will be deleted when the * application exits normally. * * @param resId The resource ID of the raw grammar resource. * @return the file representing by the unpacked grammar */ private File unpackGrammar(int resId) { Context context = mContext.get(); String extension = EXTENSION_G2G; Resources res = context.getResources(); String name = res.getResourceEntryName(resId); File grammar = context.getFileStreamPath(name + "." + extension); grammar.deleteOnExit(); try { grammar.getParentFile().mkdirs(); InputStream in = res.openRawResource(resId); FileOutputStream out = new FileOutputStream(grammar); byte[] buffer = new byte[1024]; int count = 0; while ((count = in.read(buffer)) > 0) { out.write(buffer, 0, count); } Log.i(TAG, "Unpacked base grammar to " + grammar.getPath()); return grammar; } catch (IOException e) { e.printStackTrace(); Log.e(TAG, e.toString()); return null; } }
/** * 读取对象 * * @param file * @return */ public Serializable readObject(Context ctx, String file) { if (!isExistDataCache(ctx, file)) return null; FileInputStream fis = null; ObjectInputStream ois = null; try { fis = ctx.openFileInput(file); ois = new ObjectInputStream(fis); return (Serializable) ois.readObject(); } catch (FileNotFoundException e) { } catch (Exception e) { e.printStackTrace(); // 反序列化失败 - 删除缓存文件 if (e instanceof InvalidClassException) { File data = ctx.getFileStreamPath(file); data.delete(); } } finally { try { ois.close(); } catch (Exception e) { } try { fis.close(); } catch (Exception e) { } } return null; }
// if null so erreur public ArrayList<ArticleModel> getListModel(ArrayList<Article> listes, Context context) { ArrayList<ArticleModel> listeModel = new ArrayList<>(); try { for (int i = 0; i < listes.size(); i++) { File file = context.getFileStreamPath(listes.get(i).getIdArticle() + ".png"); if (file.exists()) { Bitmap bitmap = null; BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ARGB_8888; try { bitmap = BitmapFactory.decodeStream(new FileInputStream(file), null, options); listeModel.add( new ArticleModel( bitmap, listes.get(i).getTitleArticle(), listes.get(i).getContentArticle())); } catch (FileNotFoundException e) { e.printStackTrace(); } } } return listeModel; } catch (Exception e) { e.printStackTrace(); } return null; }
private GeotriggerConfig readFromInternalStorage() { Log.v(Config.TAG, "read from internal storage"); GeotriggerConfig config = null; try { File file = mContext.getFileStreamPath(CONFIG_FILE); if (file.exists() == true) { Log.v(Config.TAG, "readFileFromInternalStorage File found..."); FileInputStream fis = mContext.openFileInput(file.getName()); StringBuilder buffer = new StringBuilder(); int ch; while ((ch = fis.read()) != -1) { buffer.append((char) ch); } Log.v(Config.TAG, "readFileFromInternalStorage complete.. " + buffer.toString()); fis.close(); config = new GeotriggerConfig(buffer.toString()); } } catch (Exception e) { Log.v(Config.TAG, "Error: " + e.getMessage()); } return config; }
private void openDataBase() throws SQLException { // Open the database mDataBase = SQLiteDatabase.openDatabase( context.getFileStreamPath(DB_NAME).toString(), null, SQLiteDatabase.OPEN_READWRITE); }
public static String getString(Context context, String chave) { chave += ".txt"; File f = context.getFileStreamPath(chave); String s = IOUtils.readString(f); Log.d(TAG, "PrefsFile.getString file: " + f + " > " + s); return s; }
@Override public void onReceive(Context context, Intent intent) { SharedPreferences sharedPrefs = context.getSharedPreferences(PREFS_NAME, 0); mSmsDisabled = sharedPrefs.getBoolean(PREFS_IS_SMS_BLOCKED, false); if (mSmsDisabled) { // Prevent other apps from receiving the SMS abortBroadcast(); List<SmsDataCache> currBlockedMsgs = new ArrayList<SmsDataCache>(); // Check if file exists with our cached messages if (context.getFileStreamPath(SMS_FILENAME).exists()) { // Build array of currently blocked messages from app's private file try { FileInputStream fis = context.openFileInput(SMS_FILENAME); ObjectInputStream ois = new ObjectInputStream(fis); try { // Read messages and updated currBlockedMsgs array. ArrayList<SmsDataCache> cachedMsgs = (ArrayList<SmsDataCache>) ois.readObject(); for (Iterator<SmsDataCache> iter = cachedMsgs.iterator(); iter.hasNext(); ) { SmsDataCache cachedMsg = iter.next(); currBlockedMsgs.add(cachedMsg); } } catch (Exception e) { e.printStackTrace(); } ois.close(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // Update private file with the message that was just received try { // Update array of blocked messages with the last received message SmsDataCache receivedMsg = new SmsDataCache(intent); currBlockedMsgs.add(receivedMsg); FileOutputStream fos = context.openFileOutput(SMS_FILENAME, Context.MODE_PRIVATE); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(currBlockedMsgs); oos.flush(); oos.close(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
private Bitmap readImageFromInternalStorage(String filename) { try { File filePath = context.getFileStreamPath(filename); FileInputStream fi = new FileInputStream(filePath); return BitmapFactory.decodeStream(fi); } catch (Exception ex) { Log.e("err in readImageFromInternalStorage()", ex.getMessage()); return null; } }
public static void setString(Context context, String chave, String valor) { try { chave += ".txt"; File file = context.getFileStreamPath(chave); FileOutputStream out = context.openFileOutput(chave, Context.MODE_PRIVATE); IOUtils.writeString(out, valor); Log.d(TAG, "PrefsFile.setString file: " + file + " > " + valor); } catch (IOException ex) { Log.e(TAG, ex.getMessage(), ex); } }
/** * Create a temp file to store the result of a download. * * @param context * @param url * @return * @throws IOException */ private static File getTemporaryFile(final Context context, final String url) throws IOException { // This is what you'd normally call to get a unique temporary // file, but for testing purposes we always name the file the // same to avoid filling up student phones with numerous // files! // return context.getFileStreamPath(Base64.encodeToString(url.getBytes(), // Base64.NO_WRAP) // + System.currentTimeMillis()); return context.getFileStreamPath(Base64.encodeToString(url.getBytes(), Base64.NO_WRAP)); }
/** * Loads the available slots in a grammar using the entries in the supplied GrammarMap. You must * load a grammar before calling this method. * * @param map A populated GrammarMap object. * @return <code>true</code> on success */ public boolean loadSlots(GrammarMap map) { Context context = mContext.get(); Resources res = context.getResources(); File cached = context.getFileStreamPath("compiled." + EXTENSION_G2G); cached.deleteOnExit(); for (Entry<String, List<GrammarEntry>> pair : map.getEntries()) { String slot = pair.getKey(); List<GrammarEntry> entries = pair.getValue(); for (GrammarEntry entry : entries) { mSrecGrammar.addWordToSlot(slot, entry.word, entry.pron, entry.weight, entry.tag); } } // Attempt to compile and save grammar to cache try { mSrecGrammar.compile(); cached.getParentFile().mkdirs(); mSrecGrammar.save(cached.getPath()); Log.i(TAG, "Compiled grammar to " + cached.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); return false; } // Destroy the old grammar mSrecGrammar.destroy(); mSrecGrammar = null; // Attempt to load new grammar from cached copy try { mGrammar = cached; mSrecGrammar = mSrec.new Grammar(cached.getPath()); mSrecGrammar.setupRecognizer(); } catch (IOException e) { e.printStackTrace(); return false; } return true; }
/** Copy the content of sourceUri to the destination. */ private Uri copyTo(final Uri sourceUri, String filename) throws IOException { Log.i( LOG_TAG, String.format("Copy a Uri to app local storage (%s -> %s)", sourceUri, filename)); final Context context = ImportVCardActivity.this; final ContentResolver resolver = context.getContentResolver(); ReadableByteChannel inputChannel = null; WritableByteChannel outputChannel = null; Uri destUri = null; try { inputChannel = Channels.newChannel(resolver.openInputStream(sourceUri)); destUri = Uri.parse(context.getFileStreamPath(filename).toURI().toString()); outputChannel = context.openFileOutput(filename, Context.MODE_PRIVATE).getChannel(); final ByteBuffer buffer = ByteBuffer.allocateDirect(8192); while (inputChannel.read(buffer) != -1) { if (mCanceled) { Log.d(LOG_TAG, "Canceled during caching " + sourceUri); return null; } buffer.flip(); outputChannel.write(buffer); buffer.compact(); } buffer.flip(); while (buffer.hasRemaining()) { outputChannel.write(buffer); } } finally { if (inputChannel != null) { try { inputChannel.close(); } catch (IOException e) { Log.w(LOG_TAG, "Failed to close inputChannel."); } } if (outputChannel != null) { try { outputChannel.close(); } catch (IOException e) { Log.w(LOG_TAG, "Failed to close outputChannel"); } } } return destUri; }
public static String ensureSuTools(Context context) { File suTools = context.getFileStreamPath("sutools"); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); int sutoolsVersion = prefs.getInt("sutoolsVersion", 0); PackageManager pm = context.getPackageManager(); int appVersionCode; try { PackageInfo info = pm.getPackageInfo(context.getPackageName(), 0); appVersionCode = info.versionCode; } catch (NameNotFoundException e) { appVersionCode = 0; } if (suTools.exists() && appVersionCode == sutoolsVersion) { return suTools.getAbsolutePath(); } Log.d(TAG, "extracting sutools"); try { copyFromAssets(context, "sutools-" + Build.CPU_ABI.split("-")[0], "sutools"); } catch (IOException e) { Log.e(TAG, "Could not extract sutools"); return null; } Process process; try { process = new ProcessBuilder() .command("chmod", "700", suTools.getAbsolutePath()) .redirectErrorStream(true) .start(); process.waitFor(); process.destroy(); } catch (IOException e) { Log.e(TAG, "Failed to set filemode of sutools"); return null; } catch (InterruptedException e) { Log.w(TAG, "process interrupted"); } prefs.edit().putInt("sutoolsVersion", appVersionCode).commit(); return suTools.getAbsolutePath(); }
private static void setUrlDrawable( final Context context, ImageView imageView, final String url, final Drawable defaultDrawable, long cacheDurationMs, final UrlImageViewCallback callback) { cleanup(context); // disassociate this ImageView from any pending downloads if (isNullOrEmpty(url)) { if (imageView != null) imageView.setImageDrawable(defaultDrawable); return; } WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); int tw = display.getWidth(); int th = display.getHeight(); if (mDeadCache == null) mDeadCache = new UrlLruCache(getHeapSize(context) / 8); Drawable drawable; BitmapDrawable zd = mDeadCache.remove(url); if (zd != null) { // this drawable was resurrected, it should not be in the live cache if (Constants.LOG_ENABLED) Log.i(Constants.LOGTAG, "zombie load"); Assert.assertTrue(!mAllCache.contains(zd)); drawable = new ZombieDrawable(url, zd); } else { drawable = mLiveCache.get(url); } if (drawable != null) { if (Constants.LOG_ENABLED) Log.i(Constants.LOGTAG, "Cache hit on: " + url); if (imageView != null) imageView.setImageDrawable(drawable); if (callback != null) callback.onLoaded(imageView, drawable, url, true); return; } // oh noes, at this point we definitely do not have the file available in memory // let's prepare for an asynchronous load of the image. final String filename = context.getFileStreamPath(getFilenameForUrl(url)).getAbsolutePath(); // null it while it is downloading if (imageView != null) imageView.setImageDrawable(defaultDrawable); // since listviews reuse their views, we need to // take note of which url this view is waiting for. // This may change rapidly as the list scrolls or is filtered, etc. if (Constants.LOG_ENABLED) Log.i(Constants.LOGTAG, "Waiting for " + url); if (imageView != null) mPendingViews.put(imageView, url); ArrayList<ImageView> currentDownload = mPendingDownloads.get(url); if (currentDownload != null) { // Also, multiple vies may be waiting for this url. // So, let's maintain a list of these views. // When the url is downloaded, it sets the imagedrawable for // every view in the list. It needs to also validate that // the imageview is still waiting for this url. if (imageView != null) currentDownload.add(imageView); return; } final ArrayList<ImageView> downloads = new ArrayList<ImageView>(); if (imageView != null) downloads.add(imageView); mPendingDownloads.put(url, downloads); final int targetWidth = tw <= 0 ? Integer.MAX_VALUE : tw; final int targetHeight = th <= 0 ? Integer.MAX_VALUE : th; final Loader loader = new Loader() { @Override public void run() { try { result = loadDrawableFromStream(context, url, filename, targetWidth, targetHeight); } catch (Exception ex) { } } }; final Runnable completion = new Runnable() { @Override public void run() { Assert.assertEquals(Looper.myLooper(), Looper.getMainLooper()); Drawable usableResult = loader.result; if (usableResult == null) usableResult = defaultDrawable; mPendingDownloads.remove(url); mLiveCache.put(url, usableResult); for (ImageView iv : downloads) { // validate the url it is waiting for String pendingUrl = mPendingViews.get(iv); if (!url.equals(pendingUrl)) { if (Constants.LOG_ENABLED) Log.i(Constants.LOGTAG, "Ignoring out of date request to update view for " + url); continue; } mPendingViews.remove(iv); if (usableResult != null) { // System.out.println(String.format("imageView: %dx%d, // %dx%d", imageView.getMeasuredWidth(), imageView.getMeasuredHeight(), // imageView.getWidth(), imageView.getHeight())); iv.setImageDrawable(usableResult); // System.out.println(String.format("imageView: %dx%d, // %dx%d", imageView.getMeasuredWidth(), imageView.getMeasuredHeight(), // imageView.getWidth(), imageView.getHeight())); if (callback != null) callback.onLoaded(iv, loader.result, url, false); } } } }; File file = new File(filename); if (file.exists()) { try { if (cacheDurationMs == CACHE_DURATION_INFINITE || System.currentTimeMillis() < file.lastModified() + cacheDurationMs) { if (Constants.LOG_ENABLED) Log.i( Constants.LOGTAG, "File Cache hit on: " + url + ". " + (System.currentTimeMillis() - file.lastModified()) + "ms old."); AsyncTask<Void, Void, Void> fileloader = new AsyncTask<Void, Void, Void>() { protected Void doInBackground(Void[] params) { loader.run(); return null; } protected void onPostExecute(Void result) { completion.run(); } }; executeTask(fileloader); return; } else { if (Constants.LOG_ENABLED) Log.i(Constants.LOGTAG, "File cache has expired. Refreshing."); } } catch (Exception ex) { } } mDownloader.download(context, url, filename, loader, completion); }
private static File getGuestDir(Context context) { if (mGuestDir == null) { mGuestDir = context.getFileStreamPath("guest"); } return mGuestDir; }
@Override public void run() { Log.i(LOG_TAG, "vCard cache thread starts running."); if (mConnection == null) { throw new NullPointerException( "vCard cache thread must be launched " + "after a service connection is established"); } mWakeLock.acquire(); try { /// M: ALPS01022668 first vcard import finished, // second vcard still caching, can't stop service in this case. mConnection.setVCardCaching(true); if (mCanceled == true) { Log.i(LOG_TAG, "vCard cache operation is canceled."); return; } final Context context = ImportVCardActivity.this; // Uris given from caller applications may not be opened twice: consider when // it is not from local storage (e.g. "file:///...") but from some special // provider (e.g. "content://..."). // Thus we have to once copy the content of Uri into local storage, and read // it after it. // // We may be able to read content of each vCard file during copying them // to local storage, but currently vCard code does not allow us to do so. int cache_index = 0; ArrayList<ImportRequest> requests = new ArrayList<ImportRequest>(); if (mSource != null) { try { requests.add(constructImportRequest(mSource, null, mDisplayName)); } catch (VCardException e) { Log.e(LOG_TAG, "Maybe the file is in wrong format", e); showFailureNotification(R.string.fail_reason_not_supported); return; } } else { final ContentResolver resolver = ImportVCardActivity.this.getContentResolver(); for (Uri sourceUri : mSourceUris) { String filename = null; // Note: caches are removed by VCardService. while (true) { filename = VCardService.CACHE_FILE_PREFIX + cache_index + ".vcf"; final File file = context.getFileStreamPath(filename); if (!file.exists()) { break; } else { if (cache_index == Integer.MAX_VALUE) { throw new RuntimeException("Exceeded cache limit"); } cache_index++; } } final Uri localDataUri = copyTo(sourceUri, filename); if (mCanceled) { Log.i(LOG_TAG, "vCard cache operation is canceled."); break; } if (localDataUri == null) { Log.w(LOG_TAG, "destUri is null"); break; } String displayName = null; Cursor cursor = null; // Try to get a display name from the given Uri. If it fails, we just // pick up the last part of the Uri. try { cursor = resolver.query( sourceUri, new String[] {OpenableColumns.DISPLAY_NAME}, null, null, null); if (cursor != null && cursor.getCount() > 0 && cursor.moveToFirst()) { if (cursor.getCount() > 1) { Log.w(LOG_TAG, "Unexpected multiple rows: " + cursor.getCount()); } int index = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); if (index >= 0) { displayName = cursor.getString(index); } } /// M: @{ } catch (Exception e) { // we just want the name. so exception should be igrnored. anyway, if // displayName is not set, the follwing code will use given uri as display name. Log.w(LOG_TAG, "exception caught ", e); /// @} } finally { if (cursor != null) { cursor.close(); } } if (TextUtils.isEmpty(displayName)) { displayName = sourceUri.getLastPathSegment(); } final ImportRequest request; try { request = constructImportRequest(null, localDataUri, displayName); } catch (VCardException e) { Log.e(LOG_TAG, "Maybe the file is in wrong format", e); /// M: Fixed cr ALPS00598462 @{ String reason = getString(R.string.fail_reason_not_supported); VcardUtils.showFailureNotification( ImportVCardActivity.this, reason, displayName, cache_index, mHandler); continue; /// @} /// Bug fix ALPS00318987 @{ } catch (IllegalArgumentException e) { LogUtils.e(LOG_TAG, "Maybe the file is in wrong format", e); /// M: Fixed cr ALPS00598462 String reason = getString(R.string.fail_reason_not_supported); VcardUtils.showFailureNotification( ImportVCardActivity.this, reason, displayName, cache_index, mHandler); continue; /// @} } catch (IOException e) { Log.e(LOG_TAG, "Unexpected IOException", e); /// M: Fixed cr ALPS00598462 @{ String reason = getString(R.string.fail_reason_io_error); VcardUtils.showFailureNotification( ImportVCardActivity.this, reason, displayName, cache_index, mHandler); continue; /// @} } if (mCanceled) { Log.i(LOG_TAG, "vCard cache operation is canceled."); return; } requests.add(request); } } if (!requests.isEmpty()) { mConnection.sendImportRequest(requests); } else { Log.w(LOG_TAG, "Empty import requests. Ignore it."); } } catch (OutOfMemoryError e) { Log.e(LOG_TAG, "OutOfMemoryError occured during caching vCard"); System.gc(); runOnUiThread( new DialogDisplayer(getString(R.string.fail_reason_low_memory_during_import))); } catch (FileNotFoundException e) { /// M: Fix ALPS00874343,if the vcf file is not exist,toast error msg. @{ LogUtils.w(LOG_TAG, "[run] the vcf file is not found when import! exception:" + e); VcardUtils.showErrorInfo(R.string.import_failure_no_vcard_file, ImportVCardActivity.this); /// @} } catch (IOException e) { Log.e(LOG_TAG, "IOException during caching vCard", e); runOnUiThread(new DialogDisplayer(getString(R.string.fail_reason_io_error))); } finally { Log.i(LOG_TAG, "Finished caching vCard."); /// M: ALPS01022668 first vcard import finished, // second vcard still caching, can't stop service in this case. mConnection.setVCardCaching(false); mWakeLock.release(); /// M: @{ if (!ImportVCardActivity.this.isFinishing() && (null != mConnection) && mConnection.isServiceBinded()) { unbindService(mConnection); mConnection = null; } else { LogUtils.d(LOG_TAG, "in VcardCacheThread, Run(), mConnection==null !!! "); } /// @} mProgressDialogForCachingVCard.dismiss(); mProgressDialogForCachingVCard = null; finish(); } }
/** * Download and shrink an Image located at a specified URL, and display it in the provided {@link * ImageView}. * * @param context A {@link Context} to allow setUrlDrawable to load and save files. * @param imageView The {@link ImageView} to display the image to after it is loaded. * @param url The URL of the image that should be loaded. * @param defaultDrawable A {@link Drawable} that should be displayed in {@code imageView} while * the image has not been loaded. This image will also be displayed if the image fails to * load. This can be set to {@code null}. * @param cacheDurationMs The length of time, in milliseconds, that this image should be cached * locally. * @param callback An instance of {@link UrlImageViewCallback} that is called when the image * successfully finishes loading. This value can be null. */ private static void setUrlDrawable( final Context context, final ImageView imageView, final String url, final Drawable defaultDrawable, final long cacheDurationMs, final UrlImageViewCallback callback) { cleanup(context); // disassociate this ImageView from any pending downloads if (isNullOrEmpty(url)) { if (imageView != null) { imageView.setImageDrawable(defaultDrawable); } return; } final int tw; final int th; if (mMetrics == null) prepareResources(context); tw = mMetrics.widthPixels; th = mMetrics.heightPixels; final String filename = context.getFileStreamPath(getFilenameForUrl(url)).getAbsolutePath(); final File file = new File(filename); if (mDeadCache == null) { mDeadCache = new UrlLruCache(getHeapSize(context) / 8); } Drawable drawable; final BitmapDrawable bd = mDeadCache.remove(url); if (bd != null) { // this drawable was resurrected, it should not be in the live cache clog("zombie load: " + url); Assert.assertTrue(url, !mAllCache.contains(bd)); drawable = new ZombieDrawable(url, bd); } else { drawable = mLiveCache.get(url); } if (drawable != null) { clog("Cache hit on: " + url); // if the file age is older than the cache duration, force a refresh. // note that the file must exist, otherwise it is using a default. // not checking for file existence would do a network call on every // 404 or failed load. if (file.exists() && !checkCacheDuration(file, cacheDurationMs)) { clog("Cache hit, but file is stale. Forcing reload: " + url); if (drawable instanceof ZombieDrawable) ((ZombieDrawable) drawable).headshot(); drawable = null; } else { clog("Using cached: " + url); } } if (drawable != null) { if (imageView != null) { imageView.setImageDrawable(drawable); } if (callback != null) { callback.onLoaded(imageView, drawable, url, true); } return; } // oh noes, at this point we definitely do not have the file available in memory // let's prepare for an asynchronous load of the image. // null it while it is downloading if (imageView != null) { imageView.setImageDrawable(defaultDrawable); } // since listviews reuse their views, we need to // take note of which url this view is waiting for. // This may change rapidly as the list scrolls or is filtered, etc. clog("Waiting for " + url); if (imageView != null) { mPendingViews.put(imageView, url); } final ArrayList<ImageView> currentDownload = mPendingDownloads.get(url); if (currentDownload != null) { // Also, multiple vies may be waiting for this url. // So, let's maintain a list of these views. // When the url is downloaded, it sets the imagedrawable for // every view in the list. It needs to also validate that // the imageview is still waiting for this url. if (imageView != null) { currentDownload.add(imageView); } return; } final ArrayList<ImageView> downloads = new ArrayList<ImageView>(); if (imageView != null) { downloads.add(imageView); } mPendingDownloads.put(url, downloads); final int targetWidth = tw <= 0 ? Integer.MAX_VALUE : tw; final int targetHeight = th <= 0 ? Integer.MAX_VALUE : th; final Loader loader = new Loader() { @Override public void run() { try { result = loadDrawableFromStream(context, url, filename, targetWidth, targetHeight); } catch (final Exception ex) { } } }; final Runnable completion = new Runnable() { @Override public void run() { Assert.assertEquals(Looper.myLooper(), Looper.getMainLooper()); Drawable usableResult = loader.result; if (usableResult == null) { usableResult = defaultDrawable; } mPendingDownloads.remove(url); mLiveCache.put(url, usableResult); if (callback != null && imageView == null) callback.onLoaded(null, loader.result, url, false); int waitingCount = 0; for (final ImageView iv : downloads) { // validate the url it is waiting for final String pendingUrl = mPendingViews.get(iv); if (!url.equals(pendingUrl)) { clog("Ignoring out of date request to update view for " + url); continue; } waitingCount++; mPendingViews.remove(iv); if (usableResult != null) { // System.out.println(String.format("imageView: %dx%d, // %dx%d", imageView.getMeasuredWidth(), imageView.getMeasuredHeight(), // imageView.getWidth(), imageView.getHeight())); iv.setImageDrawable(usableResult); // System.out.println(String.format("imageView: %dx%d, // %dx%d", imageView.getMeasuredWidth(), imageView.getMeasuredHeight(), // imageView.getWidth(), imageView.getHeight())); if (callback != null && iv == imageView) callback.onLoaded(iv, loader.result, url, false); } } clog("Populated: " + waitingCount); } }; if (file.exists()) { try { if (checkCacheDuration(file, cacheDurationMs)) { clog( "File Cache hit on: " + url + ". " + (System.currentTimeMillis() - file.lastModified()) + "ms old."); final AsyncTask<Void, Void, Void> fileloader = new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(final Void... params) { loader.run(); return null; } @Override protected void onPostExecute(final Void result) { completion.run(); } }; executeTask(fileloader); return; } else { clog("File cache has expired. Refreshing."); } } catch (final Exception ex) { } } mDownloader.download(context, url, filename, loader, completion); }
/** * 判断缓存是否存在 * * @param cachefile * @return */ private boolean isExistDataCache(Context ctx, String cachefile) { boolean exist = false; File data = ctx.getFileStreamPath(cachefile); if (data.exists()) exist = true; return exist; }
/** * Create a file to store the result of a download. * * @param context * @param url * @return * @throws IOException */ private File getTemporaryFile(final Context context, final String url) throws IOException { return context.getFileStreamPath( Base64.encodeToString(url.getBytes(), Base64.NO_WRAP) + System.currentTimeMillis()); }
/** * Download and shrink an Image located at a specified URL, and display it in the provided {@link * ImageView}. * * @param context A {@link Context} to allow setUrlDrawable to load and save files. * @param imageView The {@link ImageView} to display the image to after it is loaded. * @param url The URL of the image that should be loaded. * @param defaultDrawable A {@link Drawable} that should be displayed in {@code imageView} while * the image has not been loaded. This image will also be displayed if the image fails to * load. This can be set to {@code null}. * @param cacheDurationMs The length of time, in milliseconds, that this image should be cached * locally. * @param callback An instance of {@link UrlImageViewCallback} that is called when the image * successfully finishes loading. This value can be null. */ private static void setUrlDrawable( final Context context, final ImageView imageView, final String url, final Drawable defaultDrawable, final long cacheDurationMs, final UrlImageViewCallback callback) { assert (Looper.getMainLooper().getThread() == Thread.currentThread()) : "setUrlDrawable and loadUrlDrawable should only be called from the main thread."; cleanup(context); // disassociate this ImageView from any pending downloads if (isNullOrEmpty(url)) { if (imageView != null) { mPendingViews.remove(imageView); imageView.setImageDrawable(defaultDrawable); } return; } final int tw; final int th; if (mMetrics == null) prepareResources(context); tw = mMetrics.widthPixels; th = mMetrics.heightPixels; final String filename = context.getFileStreamPath(getFilenameForUrl(url)).getAbsolutePath(); final File file = new File(filename); // check the dead and live cache to see if we can find this url's bitmap if (mDeadCache == null) { mDeadCache = new LruBitmapCache(getHeapSize(context) / 8); } Drawable drawable = null; Bitmap bitmap = mDeadCache.remove(url); if (bitmap != null) { clog("zombie load: " + url); } else { drawable = mLiveCache.get(url); } // if something was found, verify it was fresh. if (drawable != null || bitmap != null) { clog("Cache hit on: " + url); // if the file age is older than the cache duration, force a refresh. // note that the file must exist, otherwise it is using a default. // not checking for file existence would do a network call on every // 404 or failed load. if (file.exists() && !checkCacheDuration(file, cacheDurationMs)) { clog("Cache hit, but file is stale. Forcing reload: " + url); if (drawable != null && drawable instanceof ZombieDrawable) ((ZombieDrawable) drawable).headshot(); drawable = null; bitmap = null; } else { clog("Using cached: " + url); } } // if the bitmap is fresh, set the imageview if (drawable != null || bitmap != null) { if (imageView != null) { mPendingViews.remove(imageView); if (drawable instanceof ZombieDrawable) drawable = ((ZombieDrawable) drawable).clone(mResources); else if (bitmap != null) drawable = new ZombieDrawable(url, mResources, bitmap); imageView.setImageDrawable(drawable); } // invoke any bitmap callbacks if (callback != null) { // when invoking the callback from cache, check to see if this was // a drawable that was successfully loaded from the filesystem or url. // this will be indicated by it being a ZombieDrawable (ie, something we are managing). // The default drawables will be BitmapDrawables (or whatever else the user passed in). if (bitmap == null && drawable instanceof ZombieDrawable) bitmap = ((ZombieDrawable) drawable).getBitmap(); callback.onLoaded(imageView, bitmap, url, true); } return; } // oh noes, at this point we definitely do not have the file available in memory // let's prepare for an asynchronous load of the image. // null it while it is downloading // since listviews reuse their views, we need to // take note of which url this view is waiting for. // This may change rapidly as the list scrolls or is filtered, etc. clog("Waiting for " + url + " " + imageView); if (imageView != null) { imageView.setImageDrawable(defaultDrawable); mPendingViews.put(imageView, url); } final ArrayList<ImageView> currentDownload = mPendingDownloads.get(url); if (currentDownload != null && currentDownload.size() != 0) { // Also, multiple vies may be waiting for this url. // So, let's maintain a list of these views. // When the url is downloaded, it sets the imagedrawable for // every view in the list. It needs to also validate that // the imageview is still waiting for this url. if (imageView != null) { currentDownload.add(imageView); } return; } final ArrayList<ImageView> downloads = new ArrayList<ImageView>(); if (imageView != null) { downloads.add(imageView); } mPendingDownloads.put(url, downloads); final int targetWidth = tw <= 0 ? Integer.MAX_VALUE : tw; final int targetHeight = th <= 0 ? Integer.MAX_VALUE : th; final Loader loader = new Loader() { @Override public void onDownloadComplete( UrlDownloader downloader, InputStream in, String existingFilename) { try { assert (in == null || existingFilename == null); if (in == null && existingFilename == null) return; String targetFilename = filename; if (in != null) { in = new BufferedInputStream(in, 8192); OutputStream fout = new BufferedOutputStream(new FileOutputStream(filename), 8192); copyStream(in, fout); fout.close(); } else { targetFilename = existingFilename; } result = loadBitmapFromStream(context, url, targetFilename, targetWidth, targetHeight); } catch (final Exception ex) { // always delete busted files when we throw. new File(filename).delete(); if (Constants.LOG_ENABLED) Log.e(Constants.LOGTAG, "Error loading " + url, ex); } finally { // if we're not supposed to cache this thing, delete the temp file. if (downloader != null && !downloader.allowCache()) new File(filename).delete(); } } }; final Runnable completion = new Runnable() { @Override public void run() { assert (Looper.myLooper().equals(Looper.getMainLooper())); Bitmap bitmap = loader.result; Drawable usableResult = null; if (bitmap != null) { usableResult = new ZombieDrawable(url, mResources, bitmap); } if (usableResult == null) { clog("No usable result, defaulting " + url); usableResult = defaultDrawable; mLiveCache.put(url, usableResult); } mPendingDownloads.remove(url); // mLiveCache.put(url, usableResult); if (callback != null && imageView == null) callback.onLoaded(null, loader.result, url, false); int waitingCount = 0; for (final ImageView iv : downloads) { // validate the url it is waiting for final String pendingUrl = mPendingViews.get(iv); if (!url.equals(pendingUrl)) { clog( "Ignoring out of date request to update view for " + url + " " + pendingUrl + " " + iv); continue; } waitingCount++; mPendingViews.remove(iv); if (usableResult != null) { // System.out.println(String.format("imageView: %dx%d, // %dx%d", imageView.getMeasuredWidth(), imageView.getMeasuredHeight(), // imageView.getWidth(), imageView.getHeight())); iv.setImageDrawable(usableResult); // System.out.println(String.format("imageView: %dx%d, // %dx%d", imageView.getMeasuredWidth(), imageView.getMeasuredHeight(), // imageView.getWidth(), imageView.getHeight())); // onLoaded is called with the loader's result (not what is actually used). null // indicates failure. } if (callback != null && iv == imageView) callback.onLoaded(iv, loader.result, url, false); } clog("Populated: " + waitingCount); } }; if (file.exists()) { try { if (checkCacheDuration(file, cacheDurationMs)) { clog( "File Cache hit on: " + url + ". " + (System.currentTimeMillis() - file.lastModified()) + "ms old."); final AsyncTask<Void, Void, Void> fileloader = new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(final Void... params) { loader.onDownloadComplete(null, null, filename); return null; } @Override protected void onPostExecute(final Void result) { completion.run(); } }; executeTask(fileloader); return; } else { clog("File cache has expired. Refreshing."); } } catch (final Exception ex) { } } for (UrlDownloader downloader : mDownloaders) { if (downloader.canDownloadUrl(url)) { try { downloader.download(context, url, filename, loader, completion); } catch (Exception e) { clog("Can't download from url: " + url + " Exception: " + e.getMessage()); mPendingDownloads.remove(url); if (imageView != null) { mPendingViews.remove(imageView); } } return; } } imageView.setImageDrawable(defaultDrawable); }