Can't really find words, my project just don't compile from one day to another.
This is what I do:
I download and show a PDF, later I print it as a saved PDF to the device, then the crash comes.
Here is the crash:
at java.lang.Class java.lang.Class.classForName(java.lang.String, boolean, java.lang.ClassLoader) (Class.java:-2)
at java.lang.Class java.lang.Class.forName(java.lang.String, boolean, java.lang.ClassLoader) (Class.java:453)
at java.lang.Class android.webkit.WebViewFactory.getWebViewProviderClass(java.lang.ClassLoader) (WebViewFactory.java:176)
at java.lang.Class android.webkit.WebViewFactory.getProviderClass() (WebViewFactory.java:459)
at android.webkit.WebViewFactoryProvider android.webkit.WebViewFactory.getProvider() (WebViewFactory.java:251)
at android.webkit.WebViewFactoryProvider android.webkit.WebView.getFactory() (WebView.java:2681)
at void android.webkit.WebView.ensureProviderCreated() (WebView.java:2676)
at void android.webkit.WebView.setOverScrollMode(int) (WebView.java:2741)
at void android.view.View.<init>(android.content.Context) (View.java:4815)
at void android.view.View.<init>(android.content.Context, android.util.AttributeSet, int, int) (View.java:4956)
at void android.view.ViewGroup.<init>(android.content.Context, android.util.AttributeSet, int, int) (ViewGroup.java:659)
at void android.widget.AbsoluteLayout.<init>(android.content.Context, android.util.AttributeSet, int, int) (AbsoluteLayout.java:55)
at void android.webkit.WebView.<init>(android.content.Context, android.util.AttributeSet, int, int, java.util.Map, boolean) (WebView.java:659)
at void android.webkit.WebView.<init>(android.content.Context, android.util.AttributeSet, int, int) (WebView.java:604)
at void android.webkit.WebView.<init>(android.content.Context, android.util.AttributeSet, int) (WebView.java:587)
at void android.webkit.WebView.<init>(android.content.Context, android.util.AttributeSet) (WebView.java:574)
at java.lang.Object java.lang.reflect.Constructor.newInstance0(java.lang.Object[]) (Constructor.java:-2)
at java.lang.Object java.lang.reflect.Constructor.newInstance(java.lang.Object[]) (Constructor.java:343)
at android.view.View android.view.LayoutInflater.createView(java.lang.String, java.lang.String, android.util.AttributeSet) (LayoutInflater.java:647)
at android.view.View com.android.internal.policy.PhoneLayoutInflater.onCreateView(java.lang.String, android.util.AttributeSet) (PhoneLayoutInflater.java:58)
at android.view.View android.view.LayoutInflater.onCreateView(android.view.View, java.lang.String, android.util.AttributeSet) (LayoutInflater.java:720)
at android.view.View android.view.LayoutInflater.createViewFromTag(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet, boolean) (LayoutInflater.java:788)
(The actual error is so long that I cannot post it in stackoverflow, and none of it is my own code, it has problems with Android's webview.)
Here is the activity's code where the crash happens:
public class ActivityPrintSurvey extends ActivityBase implements MVPView, View.OnClickListener, SendScannedSignedDocumentTask.SendScannedSignedDocumentCallback {
Document document;
Patient patient;
SurveyBundle surveyBundle;
View hider;
Button printBtn;
Button backBtn;
WebView webView;
ProgressBar progressBar;
Switch switcher;
boolean canPrint = false;
PrintManager printManager;
String jobName;
String fileName;
String pdfUrl;
String showPdfUrl;
private int SIGNING_DONE_1 = 105;
int runnableCounter = 0;
final int RUNNABLE_MAX = 3;
private void log(Object o) {
Log.i("PRINTING_ACT", o.toString());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_print_survey);
log("activity started");
hider = findViewById(R.id.hider);
printBtn = findViewById(R.id.print_btn);
backBtn = findViewById(R.id.back_btn);
webView = findViewById(R.id.web_view);
progressBar = findViewById(R.id.progressbar);
switcher = findViewById(R.id.read_and_accepted_switch);
document = (Document) getIntent().getSerializableExtra("document");
patient = (Patient) getIntent().getSerializableExtra("patient");
surveyBundle = (SurveyBundle) getIntent().getSerializableExtra("survey_bundle");
jobName = this.getString(R.string.app_name) + " Document";
printManager = (PrintManager) this.getSystemService(Context.PRINT_SERVICE);
printBtn.setOnClickListener(this);
backBtn.setOnClickListener(this);
showPDF();
}
private void showPDF() {
log("starting to show pdf");
pdfUrl = document.getPdfUrl();
String embedUrl = "https://docs.google.com/gview?embedded=true&url=";
showPdfUrl = embedUrl + pdfUrl;
progressBar.setVisibility(View.VISIBLE);
hider.setVisibility(View.VISIBLE);
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
if (runnableCounter < RUNNABLE_MAX) {
runnableCounter++;
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(showPdfUrl);
handler.postDelayed(this, 1000);
//Szörnyűséges a helyzet, az android szemét használhatatlan webview nem mindig jeleníti meg a pdf-et, ezért rá kell frissíteni párszor, hogy biztos megjelenítse, ez van.
} else {
progressBar.setVisibility(View.GONE);
hider.setVisibility(View.GONE);
}
}
};
handler.post(runnable);
downloadPDF();
}
public void downloadPDF() {
log("starting to download pdf");
fileName = FileHelper.generateTempFileName();
ANRequest.DownloadBuilder downloadBuilder = AndroidNetworking.download(pdfUrl, FileHelper.getTempFileDirectory(this), fileName);
downloadBuilder.doNotCacheResponse();
ANRequest request = downloadBuilder.build();
request.setDownloadProgressListener(new DownloadProgressListener() {
@Override
public void onProgress(long bytesDownloaded, long totalBytes) {
// do anything with progress
Log.i("ON_PROGRESS", bytesDownloaded + " / " + totalBytes);
}
}).startDownload(new DownloadListener() {
@Override
public void onDownloadComplete() {
// do anything after completion
canPrint = true;
}
@Override
public void onError(ANError error) {
// handle error
Toast.makeText(ActivityPrintSurvey.this, error.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
public void print() {
log("starting to print");
printManager.print(jobName, new PrintDocumentAdapter() {
@Override
public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback) {
InputStream input = null;
OutputStream output = null;
log("onWrite() called for printing");
try {
File file = FileHelper.readTempFile(ActivityPrintSurvey.this, fileName);
input = new FileInputStream(file);
output = new FileOutputStream(destination.getFileDescriptor());
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buf)) > 0) {
output.write(buf, 0, bytesRead);
}
callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES});
log("onWriteFinished() called for printing");
} catch (Exception e) {
//Catch exception
e.printStackTrace();
log("Exception 1: " + e.getMessage());
} finally {
try {
input.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
log("Exception 2: " + e.getMessage());
}
}
}
@Override
public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras) {
log("onLayout() done");
if (cancellationSignal.isCanceled()) {
callback.onLayoutCancelled();
log("onLayoutCancelled()");
return;
}
PrintDocumentInfo pdi = new PrintDocumentInfo.Builder(fileName/*Ez itt lehet bármi, kiskutya füle, nem kell megegyeznie az alap file nevvel*/).setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build();
callback.onLayoutFinished(pdi, true);
log("onLayoutFinished() called");
}
@Override
public void onFinish() {
FileHelper.deleteTempFiles(ActivityPrintSurvey.this);
log("onFinish() done");
// ha kész a nyomtatás, jöhet a valós aláírás tollal, majd visszafotózás, és feltöltés
new AlertDialog.Builder(ActivityPrintSurvey.this)
.setTitle(getString(R.string.next_step))
.setMessage(getString(R.string.please_scan_the_printed_and_signed_document))
.setPositiveButton(getString(R.string.scan), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
startScanningByCameraPhoto();
}
})
.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.show();
log("showing alert dialog");
}
}, null);
}
public void startScanningByCameraPhoto() {
// start picker to get image for cropping and then use the image in cropping activity
CropImage.activity()
.setGuidelines(CropImageView.Guidelines.ON)
.start(this);
log("startScanningByCameraPhoto");
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
log("onActivityResult called");
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SIGNING_DONE_1) {
log("RESULT_OK from SIGNING_DONE_1 -> calling .finish()");
Intent intent = new Intent();
intent.putExtra("document", document);
setResult(Activity.RESULT_OK, intent);
finish();
}
} else {
log("1. Error: resultCode NOT RESULT OK");
}
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == RESULT_OK) {
log("RESULT_OK from CROP_IMAGE_ACTIVITY_REQUEST_CODE");
Uri resultUri = result.getUri();
File file = new File(resultUri.getPath());
showLoading();
SendScannedSignedDocumentTask task = new SendScannedSignedDocumentTask(this, this, DatabaseHelper.getInstance().readLoggedInUser().getUserToken(), document, patient, file);
task.execute();
} else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
Exception error = result.getError();
log("2. Error: resultCode NOT RESULT OK: " + error.getMessage());
error.printStackTrace();
}
}
}
@Override
public void handleUploadScannedDocumentAPIDone(String error) {
hideLoading();
if (error != null) {
log("handleUploadScannedDocumentAPIDone, error:" + error);
DialogHelper.showInfo(this, error);
} else {
log("handleUploadScannedDocumentAPIDone -> finishing()");
setResult(Activity.RESULT_OK);
Toast.makeText(this, "✔ " + getString(R.string.uploaded), Toast.LENGTH_LONG).show();
finish();
}
}
@Override
public void onClick(View v) {
if (v.equals(printBtn)) {
if (switcher.isChecked()) {
if (canPrint) {
print();
} else {
Toast.makeText(this, "PDF not found in device. Retrying download...", Toast.LENGTH_LONG).show();
downloadPDF();
}
} else {
DialogHelper.showInfo(this, getString(R.string.please_check_the_checkbox));
}
} else if (v.equals(backBtn)) {
onBackPressed();
}
}
public void hideLoading() {
progressBar.setVisibility(View.GONE);
}
@Override
public void showLoading() {
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void showError(String error, String code) {
hideLoading();
canPrint = false;
DialogHelper.showError(this, error);
log("showing error: " + error);
}
@Override
public void showSuccess(Object... object) {
hideLoading();
String api = object[0].toString();
if (api.equals("eject_patient")) {
log("showSuccess: " + "finishing activity.");
Intent intent = new Intent(this, ActivityWaitingForPatient.class);
startActivity(intent);
finish();
} else {
log("showSuccess: " + "ERROR: " + api + " not equals " + "eject_patient");
}
}
@Override
public void onResume() {
super.onResume();
LayoutTextSizeChanger.changeAllTextSizeInLayout((ViewGroup) findViewById(R.id.main_cont), FontUtil.loadFontSize(this));
log("onResume()" );
}
}
I'm experiencing the same exception and immense stack trace when using WebView in my app at runtime, depending on the software versions installed on the device:
Chrome Versions:
Android Versions:
android.webkit.TracingControllerandroid.webkit.PacProcessorAccording to your description and stack trace, you see this error at runtime, not at compile time, right? So, I would recommend to
Hmmm... intermittent problem that references class loader issues. + a huge stack trace.
What little evidence you provided may point to silent IO-type errors.
Say for example the android you're using is dynamically loading classes at runtime and for some reason the host folder for whatever jars it's trying to use also contains that pdf file which is actively written to / read from ... or for whatever reason, that entire fileSystem partition is marked as locked.
In that case you'd wind up with intermittent class loader errors like the one you referenced.
also this:
try {
input.close(); <--- if exception occurs at this point, output will never close.
output.close();
} catch (IOException e) {
e.printStackTrace();
log("Exception 2: " + e.getMessage());
}
... I don't know... there's very little information to go by to be honest. For example you didn't post the content of the finish() routine, and that stack trace contains no references to your code (that i can see at least)... so this is kind of a wild stab in the dark.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With