2016-09-29 7 views
1

Wir arbeiten an einer App mit PDFTron. Wir haben festgestellt, dass beim Öffnen der Activity, die den zugewiesenen Speicher anzeigt, sich der Speicherplatz erhöht. Nach dem Navigieren weg von der Aktivität wird nur ein Teil des Speichers wieder freigegeben. Einige PDFtron-Teile bleiben zurück.PDFViewCtrl nicht entfernt

enter image description here

Das Problem ist, dass die Aktivität nicht einmal zu Ende scheint aber, dass wir die Aktivität Nohistory und singleTask gesetzt haben. Ich habe einige Kurse zur Speicherverwaltung verfolgt, kann aber nicht herausfinden, warum die Aktivität offen bleibt.

Bevor wir anrufen, verfügen wir über die PdfViewCtrl. Dann in der OnDestroy:

protected override void OnDestroy() 
{ 
    base.OnDestroy(); 
    if (_mPdfViewCtrl == null) return; 
    _mPdfViewCtrl.Destroy(); 
    _mPdfViewCtrl = null; 
} 

Wenn die App für eine lange Periode der Zeit verwendet wird, führt dies zu einem Out-of-Memory-Fehler.

--- End of managed Java.Lang.Error stack trace --- 
java.lang.OutOfMemoryError 
dalvik.system.NativeStart.run(Native Method):0 

oder

--- End of managed Java.Lang.Error stack trace --- 
java.lang.OutOfMemoryError 
android.graphics.Bitmap.nativeCreate(Native Method):0 
android.graphics.Bitmap.createBitmap(Bitmap.java:726):0 
android.graphics.Bitmap.createBitmap(Bitmap.java:703):0 
android.graphics.Bitmap.createBitmap(Bitmap.java:670):0 
pdftron.PDF.Utils.SignaturePickerDialog$SignatureView.onSizeChanged(SignaturePickerDialog.java:244):0 
android.view.View.sizeChange(View.java:15326):0 
android.view.View.setFrame(View.java:15290):0 
android.view.View.layout(View.java:15201):0 
android.widget.RelativeLayout.onLayout(RelativeLayout.java:1076):0 
android.view.View.layout(View.java:15204):0 
android.view.ViewGroup.layout(ViewGroup.java:4793):0 
android.widget.FrameLayout.onLayout(FrameLayout.java:448):0 
android.view.View.layout(View.java:15204):0 
android.view.ViewGroup.layout(ViewGroup.java:4793):0 
android.widget.RelativeLayout.onLayout(RelativeLayout.java:1076):0 
android.view.View.layout(View.java:15204):0 
android.view.ViewGroup.layout(ViewGroup.java:4793):0 
android.widget.FrameLayout.onLayout(FrameLayout.java:448):0 
android.view.View.layout(View.java:15204):0 
android.view.ViewGroup.layout(ViewGroup.java:4793):0 
android.widget.FrameLayout.onLayout(FrameLayout.java:448):0 
android.view.View.layout(View.java:15204):0 
android.view.ViewGroup.layout(ViewGroup.java:4793):0 
android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677):0 
android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531):0 
android.widget.LinearLayout.onLayout(LinearLayout.java:1440):0 
android.view.View.layout(View.java:15204):0 
android.view.ViewGroup.layout(ViewGroup.java:4793):0 
android.widget.FrameLayout.onLayout(FrameLayout.java:448):0 
android.view.View.layout(View.java:15204):0 
android.view.ViewGroup.layout(ViewGroup.java:4793):0 
android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677):0 
android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531):0 
android.widget.LinearLayout.onLayout(LinearLayout.java:1440):0 
android.view.View.layout(View.java:15204):0 
android.view.ViewGroup.layout(ViewGroup.java:4793):0 
android.widget.FrameLayout.onLayout(FrameLayout.java:448):0 
android.view.View.layout(View.java:15204):0 
android.view.ViewGroup.layout(ViewGroup.java:4793):0 
android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2263):0 
android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2009):0 
android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1251):0 
android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6379):0 
android.view.Choreographer$CallbackRecord.run(Choreographer.java:791):0 
android.view.Choreographer.doCallbacks(Choreographer.java:591):0 
android.view.Choreographer.doFrame(Choreographer.java:561):0 
android.view.Choreographer$FrameHandler.handleMessage(Choreographer.java:693):0 
android.os.Handler.dispatchMessage(Handler.java:99):0 
android.os.Looper.loop(Looper.java:137):0 
android.app.ActivityThread.main(ActivityThread.java:5493):0 
java.lang.reflect.Method.invokeNative(Native Method):0 
java.lang.reflect.Method.invoke(Method.java:525):0 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209):0 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025):0 
dalvik.system.NativeStart.main(Native Method):0 

Unterhalb einer Druckbild von einer simulierten Sitzung (Android Studio Monitoring): enter image description here

Edited OnDestroy:

 var old_tool = _mPdfViewCtrl.ToolManager; 
     var old_doc = _mPdfViewCtrl.Doc; 
     _mPdfViewCtrl?.CloseDoc(); 
     _mPdfViewCtrl?.CloseTool(); 
     _mPdfViewCtrl?.Destroy(); 
     _mPdfViewCtrl = null; 
     _mPdfViewCtrl?.Dispose(); 
     if (old_doc != null) 
     { 
      old_doc.Dispose(); 
     } 

     if (old_tool != null) 
     { 
      old_tool.Dispose(); 
     } 

enter image description here

+0

Können Sie mithilfe des PDFViewCtrl-Beispielprojekts reproduzieren, das mit dem SDK geliefert wird? Oder passiert das nur in Ihrem Projekt? – Ryan

+0

@Ryan Danke für die Antwort. Ich habe gerade einen neuen Link vom Support-Team von pdftron erhalten. Ich werde das in dieser Woche testen. –

Antwort

1

Wenn Ihre Aktivität auch einen Verweis auf ein PDFDoc-Objekt enthält, sollten Sie auch darüber verfügen. Dies ist der empfohlene Weg.

protected override void OnDestroy() 
{ 
    base.OnDestroy(); 
    if (_mPdfViewCtrl == null) return; 
    _mPdfViewCtrl.Destroy(); 
    _mPdfViewCtrl = null; 
    if(_mPdfDoc != null) 
    { 
     _mPdfDoc.Dispose(); 
    } 
} 

oder allgemeine

protected override void OnDestroy() 
{ 
    base.OnDestroy(); 
    if (_mPdfViewCtrl == null) return; 
    PDFDoc old_doc = _mPdfViewCtrl.Doc; 
    _mPdfViewCtrl.Destroy(); 
    _mPdfViewCtrl = null; 
    if(old_doc != null) 
    { 
     old_doc.Dispose(); 
    } 
} 
+0

Vielen Dank für diese Lösung. Ich werde es versuchen und Ihnen das Ergebnis wissen –

+0

In der aktuellen Version verwenden wir _mPdfViewCtrl hat keine Methode namens GetDoc(). Der Link, den ich erhielt, war für das native SDK. Ich bekomme das Xamarin SDK Ich werde es versuchen. –

+0

Ich habe meinen Awnser bearbeitet. Würde das den gleichen Effekt haben? Wenn das so wäre, würde das nicht funktionieren. Ich habe auch eine neue Monitorsitzung hinzugefügt. Wenn das nicht dasselbe ist, müssten wir auf den neuen Link warten. –

2

Von diesem link:

„Q: Ich habe eine Seite, wo der Benutzer Dateien auswählt, und eine andere, wo der Benutzer die ausgewählten PDF-Ansichten, wenn die. Der Benutzer navigiert von der PDF-Anzeigeseite zurück zur Dateiseite, ich möchte die Ressourcen bereinigen, die von PDFNet verwendet werden.Was ist die richtige Reihenfolge zum Bereinigen der Tools, der PDFViewCtrl und der PDFDoc-Datei?

A: Sie müssen zuerst PDFViewCtrl.CloseDoc() aufrufen und dann PDFDoc.Dispose() aufrufen. Das ist gut in OnNavigatedFrom für jede Seite, die die PDFViewCtrl verwendet.

Auch kann die PDFViewCtrl nicht manuell entsorgt werden, stattdessen haben wir ein PDFViewCtrl.FreeResources hinzugefügt, der alle darunter liegenden Strukturen entfernt, was bedeutet, weniger Speicher, bis der Garbage Collector Kicks verwendet wird.

Ich mag an folgendes hinzufügen:

 PDFDoc doc = this.PDFViewCtrl.GetDoc(); 

     this.PDFViewCtrl.CloseDoc(); 


     if (doc != null) 
     { 
      await CloseDocAsync(doc); 
     } 

     this.PDFViewCtrl.FreeResources(); 

Wo CloseDocAsync nur Anrufe doc.Dispose in einem Hintergrund-Thread (in Fall ist es ein großes, kompliziertes Dokument). Dies ist möglicherweise nicht notwendig, da alle mir bekannten Dokumente recht schnell entsorgt werden. Aber es tut nicht weh. Sogar 200 ms Verzögerung auf dem UI-Thread könnten störend sein.

Eine Sache zu beachten ist, dass für die erneute Beanstandung der PDFViewCtrl durch den Garbage Collector alle registrierten Ereignisse nicht registriert werden müssen. Deshalb sollte die ToolManager.Dispose() aufgerufen werden, wenn Sie auch von einer Seite weg navigieren. In diesem Fall rufen Sie einfach ToolManager.Dispose vor jeder der Code, den ich oben gegeben.“

Wenn keine der oben genannten hilft, könnten Sie forum Wieder veröffentlichen Sie Ihre Frage im PDFTron versuchen. Das Unternehmen hat auch eine tech support option dass die Priorität technischen Support zur Verfügung stellt. Je nach Version, die Sie verwenden, kann der Tech-Support-frei sein.

EDIT

die Links, die ich für die Dokumentation gab, war für die Windows-Version, nicht für Android. Hier sind die Android Version Links für PDFViewCtrl und PDFDoc.

Also, der Code von dem Link, den ich oben gab, wird nicht für Sie arbeiten. Was Sie stattdessen versuchen könnten, ist das Schließen des Dokuments. Es gibt eine CloseDoc-Methode, die von der PDFViewCtrl-Klasse aufgerufen werden kann. Wenn dies nicht funktioniert, versuchen Sie, die Close-Methode der PDFDoc-Methode aufzurufen. Die PDFViewCtrl-Klasse hat eine Methode namens getDoc, die das aktuelle Dokument zurückgibt, das ein PDFDoc ist. Die Dokumentation besagt, dass die PDFDoc.close-Methode ein Destruktor ist. Also, probiere diese beiden Ideen aus.

Eine andere Sache, die ich bemerkte, ist, dass es Methoden zum Sperren und Entsperren in der PDFViewCtrl-Klasse gibt. Sie könnten versuchen, die Methode docUnlock aufzurufen, bevor Sie die Methode close aufrufen, wenn die obigen zwei Ideen nicht funktionieren. Die Idee ist, dass der Aufruf zum Schließen entweder hängen bleibt oder ausläuft, wenn das Dokument gesperrt ist.

Nun, wenn nichts davon funktioniert, gibt es dann noch etwas, das Sie kaputt machen? Ist es möglich, dass Sie oder jemand anderes in Ihrer Gruppe vergessen, Speicher für etwas anderes aufzuräumen? Benutzt jemand C++ oder verwendet vielleicht eine API, die C++ darunter verwendet und es vernachlässigt, den Speicher zu löschen, oder die entsprechende close-Methode aufruft, um sauber zu bereinigen?

Die Verwendung eines Profilers kann helfen, diese Fragen zu beantworten. Es gibt 3rd Party Profiler zur Verfügung oder Sie können versuchen, die Microsoft .NET Memory Analyzer. Ich weiß nicht, ob es Android funktioniert. Es erfordert auch Version 4.5 oder höher von .NET Framework.

Es gibt auch eine Xamarin profiler, die wahrscheinlich eine bessere Wahl ist, mit zu beginnen.

+0

Hallo Bob, ich werde dies versuchen, sobald ich einen neuen Link bekomme. Die aktuelle Version verfügt nicht über die Methoden GetDoc und FreeResources. –

+0

Gemäß der [Dokumentation] (http: //www.pdftron.com/pdfnet/PDFNet/html/AllMembers_T_pdftron_PDF_PDFViewCtrl.htm), steht die GetDoc-Methode zur Verfügung. Verwenden Sie eine ältere Version? Ich habe FreeResources in der Dokumentation nicht angezeigt. Sie können versuchen, die überladene Methode Dispose (true) aufzurufen, um sowohl verwaltete als auch nicht verwaltete Ressourcen freizugeben. Dies sowohl für PDFViewCtrl als auch für das Objekt [PDFDoc] (http://www.pdftron.com/pdfnet/PDFNet/html/AllMembers_T_pdftron_PDF_PDFDoc.htm). –

+0

Ich denke schon. Ich habe das Team nach einem Xamarin-Link gefragt, da der Link, den wir erhalten haben, für native Android gedacht war. –