我一直在寻找解决问题的方法。最常见的建议是将android:hardwareAccelerated =“false”和android:largeHeap =“true”添加到清单中的应用程序标记,但是我仍然会收到以下错误:
E/UncaughtException: java.lang.OutOfMemoryError: Failed to allocate a 56272 byte allocation with 19848 free bytes and 19KB until OOM
at java.lang.StringBuilder.toString(StringBuilder.java:408)
at org.chromium.content_public.browser.LoadUrlParams.buildDataUri(LoadUrlParams.java:113)
at org.chromium.content_public.browser.LoadUrlParams.createLoadDataParamsWithBaseUrl(LoadUrlParams.java:164)
at org.chromium.android_webview.AwContents.loadDataWithBaseURL(AwContents.java:1523)
at com.android.webview.chromium.WebViewChromium.loadDataWithBaseURL(WebViewChromium.java:609)
at android.webkit.WebView.loadDataWithBaseURL(WebView.java:1015)
at com.google.android.gms.internal.zzakn.loadDataWithBaseURL(Unknown Source)
at com.google.android.gms.internal.zzakm.loadDataWithBaseURL(Unknown Source)
at com.google.android.gms.internal.zzxy.zzgo(Unknown Source)
at com.google.android.gms.internal.zzxq.zzgp(Unknown Source)
at com.google.android.gms.internal.zzxw.zza(Unknown Source)
at com.google.android.gms.ads.internal.zzl.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.OutOfMemoryError: Failed to allocate a 56272 byte allocation with 19848 free bytes and 19KB until OOM
at java.lang.StringBuilder.toString(StringBuilder.java:408)
at org.chromium.content_public.browser.LoadUrlParams.buildDataUri(LoadUrlParams.java:113)
at org.chromium.content_public.browser.LoadUrlParams.createLoadDataParamsWithBaseUrl(LoadUrlParams.java:164)
at org.chromium.android_webview.AwContents.loadDataWithBaseURL(AwContents.java:1523)
at com.android.webview.chromium.WebViewChromium.loadDataWithBaseURL(WebViewChromium.java:609)
at android.webkit.WebView.loadDataWithBaseURL(WebView.java:1015)
at com.google.android.gms.internal.zzakn.loadDataWithBaseURL(Unknown Source)
at com.google.android.gms.internal.zzakm.loadDataWithBaseURL(Unknown Source)
at com.google.android.gms.internal.zzxy.zzgo(Unknown Source)
at com.google.android.gms.internal.zzxq.zzgp(Unknown Source)
at com.google.android.gms.internal.zzxw.zza(Unknown Source)
at com.google.android.gms.ads.internal.zzl.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
所以我的活动可能参与其中,不幸的是我迷失了,不知道要解决什么来解决这个问题。
Gridviewadapter
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class GridViewAdapter extends ArrayAdapter<ImageItem> {
private Context context;
private int layoutResourceId;
private ArrayList<ImageItem> data = new ArrayList<ImageItem>();
public GridViewAdapter(Context context, int layoutResourceId, ArrayList<ImageItem> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.imageTitle = (TextView) row.findViewById(R.id.text);
holder.image = (ImageView) row.findViewById(R.id.image);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
ImageItem item = data.get(position);
holder.imageTitle.setText(item.getTitle());
holder.image.setImageBitmap(item.getImage());
return row;
}
static class ViewHolder {
TextView imageTitle;
ImageView image;
}
}
的ImageItem
import android.graphics.Bitmap;
public class ImageItem {
private int arrayIndex;
private Bitmap image;
private String title;
public ImageItem(int arrayIndex, Bitmap image, String title) {
super();
this.arrayIndex = arrayIndex;
this.image = image;
this.title = title;
}
public Bitmap getImage() {
return image;
}
public void setImage(Bitmap image) {
this.image = image;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getArrayIndex() {
return arrayIndex;
}
public void setArrayIndex(int arrayIndex) {
this.arrayIndex = arrayIndex;
}
}
Mainactivity
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import java.util.ArrayList;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.firebase.iid.FirebaseInstanceId;
public class MainActivity extends ActionBarActivity {
private GridView gridView;
private GridViewAdapter gridAdapter;
private Toolbar toolbar;
private static final String TAG = MainActivity.class.getSimpleName();
private static final int STORAGE_PERMISSION_REQUEST = 2001;
AdRequest adRequest;
AdView mAdView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//loading ads
loadAds();
toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.drawable.home_icon);
getSupportActionBar().setDisplayUseLogoEnabled(true);
gridView = (GridView) findViewById(R.id.gridView);
gridAdapter = new GridViewAdapter(this, R.layout.grid_item_layout, getData());
gridView.setAdapter(gridAdapter);
isStoragePermissionGranted();
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
ImageItem item = (ImageItem) parent.getItemAtPosition(position);
//Create intent
Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
intent.putExtra("title", item.getTitle());
intent.putExtra("index", item.getArrayIndex());
//Start details activity
startActivity(intent);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id==R.id.navigate) {
startActivity(new Intent(this, SettingsActivity.class));
}
return super.onOptionsItemSelected(item);
}
private void loadAds() {
mAdView = (AdView) findViewById(R.id.adView);
adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
}
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission is granted");
return true;
} else {
Log.v(TAG, "Permission is revoked");
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
1);
return false;
}
} else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG, "Permission is granted");
return true;
}
}
@Override
public void onRequestPermissionsResult(
int requestCode,
String[] permissions,
int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == STORAGE_PERMISSION_REQUEST) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Permission: " + permissions[0] + "was " + grantResults[0]);
// resume tasks needing this permission
} else {
// TODO: You should not allow the user to continue!
}
}
}
/**
* Prepare some dummy data for gridview
*/
private ArrayList<ImageItem> getData() {
final ArrayList<ImageItem> imageItems = new ArrayList<>();
TypedArray imgs = getResources().obtainTypedArray(R.array.image_ids);
for (int i = 0; i < imgs.length(); i++) {
Log.d(TAG, "Image ID: " + String.valueOf(i));
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs.getResourceId(i, -1));
imageItems.add(new ImageItem(i, bitmap, "Image#" + i));
}
return imageItems;
}
}
Detailsactivity
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.StringTokenizer;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.InterstitialAd;
public class DetailsActivity extends ActionBarActivity {
Button btnShare;
private InterstitialAd interstitialAd;
boolean exitApp=false;
private Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.details_activity);
toolbar = (Toolbar) findViewById(R.id.app_bar);
TextView titleTextView = (TextView) findViewById(R.id.title);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.drawable.home_icon);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
String title = getIntent().getStringExtra("title");
int index = getIntent().getIntExtra("index", -1);
// Worked on by Douglas
if(title!=null){
titleTextView.setText(title);
}else{
titleTextView.setText("No title");
}
Bitmap bitmap = getBitmap(0);
try{
bitmap = getBitmap(index);
}catch (Exception e){
Log.d("getBitmap Broke: ", e.toString());
}
// Till here
ImageView imageView = (ImageView) findViewById(R.id.image);
imageView.setImageBitmap(bitmap);
String imgBitmapPath= MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, title ,null);
final Uri imgBitmapUri=Uri.parse(imgBitmapPath);
btnShare=(Button)findViewById(R.id.button);
btnShare.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Get the URI
// Replace R.drawable.image with the name of the image you want to display
//Uri uri = Uri.parse("android.resource://" + BuildConfig.APPLICATION_ID + "/" + R.drawable.image_1);
// Now that you have the URI you can create your intent
Intent share = new Intent(Intent.ACTION_SEND);
share.putExtra(Intent.EXTRA_STREAM, imgBitmapUri);
share.setType("image/*");
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// Create a chooser to share your emoji
try {
DetailsActivity.this.startActivity(Intent.createChooser(share, "Share Emoji"));
} catch (ActivityNotFoundException e) {
// Whatsapp might not be installed
}
}
});
launchInter();
loadInterstitial();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id==R.id.navigate) {
startActivity(new Intent(this, SettingsActivity.class));
}
return super.onOptionsItemSelected(item);
}
/**
* Prepare some dummy data for gridview
*/
private Bitmap getBitmap(int index) {
final ArrayList<ImageItem> imageItems = new ArrayList<>();
TypedArray imgs = getResources().obtainTypedArray(R.array.image_ids);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs.getResourceId(index, -1));
return bitmap;
}
private void launchInter() {
interstitialAd = new InterstitialAd(this);
interstitialAd.setAdUnitId("ca-app-pub-7350914179187171/1372559648");
interstitialAd.setAdListener(new AdListener() {
@Override
public void onAdLoaded() {
showAdInter();
}
@Override
public void onAdFailedToLoad(int errorCode) {
String message=String.format("onAdFailedToLoad (%s)",getErrorReason(errorCode));
}
@Override
public void onAdClosed() {
if (exitApp)
finish();
}
});
}
private void showAdInter() {
if (interstitialAd.isLoaded()) {
interstitialAd.show();
}
else
{
Log.d("","Interstitial ad was not ready to be shown");
}
}
public void loadInterstitial() {
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.addTestDevice("Insert_your_hashed_device_id_here")
.build();
interstitialAd.loadAd(adRequest);
}
private String getErrorReason(int errorCode) {
String errorReason="";
switch(errorCode) {
case AdRequest.ERROR_CODE_INTERNAL_ERROR:
errorReason="Internal Error";
break;
case AdRequest.ERROR_CODE_INVALID_REQUEST:
errorReason="Invalid Request";
break;
case AdRequest.ERROR_CODE_NETWORK_ERROR:
errorReason="Network Error";
break;
case AdRequest.ERROR_CODE_NO_FILL:
errorReason="No Fill";
break;
}
return errorReason;
}
}
我真的很感激任何帮助!
答案 0 :(得分:1)
我的建议是修改您的代码,以便从Bitmap
类中删除ImageItem
个实例,如下所示
public class ImageItem {
private int arrayIndex;
private int imageResource;
private String title;
public ImageItem(int arrayIndex, int imageResource, String title) {
super();
this.arrayIndex = arrayIndex;
this.imageResource = imageResource;
this.title = title;
}
public int getImageResource() {
return imageResource;
}
public void setImageResource(int imageResource) {
this.imageResource = imageResource;
}
// rest methods should be same
}
在GridViewAdapter
类中加载来自资源ID的图像,如下所示
public class GridViewAdapter extends ArrayAdapter<ImageItem> {
// your old logic here
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// your old logic here
// holder.image.setImageBitmap(item.getImage());
Picasso.with(context).load(item.getImageResource()).into(holder.image);
}
// your old logic here
}
修改getData
MainActivity.java
方法
private ArrayList<ImageItem> getData() {
final ArrayList<ImageItem> imageItems = new ArrayList<>();
TypedArray imgs = getResources().obtainTypedArray(R.array.image_ids);
for (int i = 0; i < imgs.length(); i++) {
Log.d(TAG, "Image ID: " + String.valueOf(i));
// no need to load image here
// Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs.getResourceId(i, -1));
imageItems.add(new ImageItem(i, imgs.getResourceId(i, -1), "Image#" + i));
}
return imageItems;
}
最后一个在app build.gradle
中添加编译依赖项,如下所示
dependencies {
...
compile 'com.squareup.picasso:picasso:2.5.0'
...
}
并完成。