最高の Android PDF ライブラリ
今年のベスト Android PDF ライブラリ。
PDFはPortable Document Formatの略です。 これは、アプリケーション ソフトウェア、ハードウェア、オペレーティング システムに依存しない方法で、テキスト形式や画像を含むドキュメントを表示するために 1990 年代に開発されたファイル形式です。
PDF は 24 年前の「1993 年 6 月 15 日」に Adobe によって初めてリリースされましたが、現在は国際標準化機構 (ISO) によって維持されているオープン標準です。
Android デバイスには無料および商用の PDF リーダー アプリケーションがたくさんあります。 ただし、開発者として、私たちや友人が使用できる独自の小さな PDF リーダーを構築する必要があります。
これは思っているほど難しくはなく、これを支援するオープンソース ライブラリがいくつか存在します。
この記事では、これらのライブラリのいくつかと、おそらくそれらの使用方法の断片を見ていきます。
はじめましょう。
1. AndroidPdfViewer
これは PDF ドキュメントを表示するためのオープン ソース ライブラリです。これらの PDF は PdfiumAndroid でレンダリングされます。
AndroidPdfViewer は、現在最も人気のある Android PDF ビュー ライブラリです。 これは bartesk によって保守されており、彼はライブラリのさまざまなバージョンを独自にリリースしています。
たとえば、多くの人がまだ AndroidPdfView を使用していますが、AndroidPdfViewV1 と [AndroidPdfViewV2] も存在します。 (https://github.com/barteksc/AndroidPdfViewerV2)。
このライブラリは、「アニメーション」、「ジェスチャー」、「ズーム」、「ダブルタップ」のサポートを備えています。
このライブラリの使用は簡単、非常に簡単です。
まず、それをアプリレベルの build.gradle に含めるだけです。
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
次に、レイアウト内で次のようにします。
<com.github.barteksc.pdfviewer.PDFView
android_id="@+id/pdfView"
android_layout_width="match_parent"
android_layout_height="match_parent"/>
その後、さまざまなソースから PDF をロードできます。
pdfView.fromUri(Uri)
or
pdfView.fromFile(File)
or
pdfView.fromBytes(byte[])
or
pdfView.fromStream(InputStream) // stream is written to bytearray - native code cannot use Java Streams
or
pdfView.fromSource(DocumentSource)
or
pdfView.fromAsset(String)
.pages(0, 2, 1, 3, 3, 3) // all pages are displayed by default
.enableSwipe(true) // allows to block changing pages using swipe
.swipeHorizontal(false)
.enableDoubletap(true)
.defaultPage(0)
// allows to draw something on the current page, usually visible in the middle of the screen
.onDraw(onDrawListener)
// allows to draw something on all pages, separately for every page. Called only for visible pages
.onDrawAll(onDrawListener)
.onLoad(onLoadCompleteListener) // called after document is loaded and starts to be rendered
.onPageChange(onPageChangeListener)
.onPageScroll(onPageScrollListener)
.onError(onErrorListener)
.onPageError(onPageErrorListener)
.onRender(onRenderListener) // called after document is rendered for the first time
// called on single tap, return true if handled, false to toggle scroll handle visibility
.onTap(onTapListener)
.enableAnnotationRendering(false) // render annotations (such as comments, colors or forms)
.password(null)
.scrollHandle(null)
.enableAntialiasing(true) // improve rendering a little bit on low-res screens
// spacing between pages in dp. To define spacing color, set view background
.spacing(0)
.invalidPageColor(Color.WHITE) // color of page that is invalid and cannot be loaded
.load();
### 例
ここに例があります
@EActivity(R.layout.activity_main)
@OptionsMenu(R.menu.options)
public class PDFViewActivity extends AppCompatActivity implements OnPageChangeListener, OnLoadCompleteListener,
OnPageErrorListener {
private static final String TAG = PDFViewActivity.class.getSimpleName();
private final static int REQUEST_CODE = 42;
public static final int PERMISSION_CODE = 42042;
public static final String SAMPLE_FILE = "sample.pdf";
public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
@ViewById
PDFView pdfView;
@NonConfigurationInstance
Uri uri;
@NonConfigurationInstance
Integer pageNumber = 0;
String pdfFileName;
@OptionsItem(R.id.pickFile)
void pickFile() {
int permissionCheck = ContextCompat.checkSelfPermission(this,
READ_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
new String[]{READ_EXTERNAL_STORAGE},
PERMISSION_CODE
);
return;
}
launchPicker();
}
void launchPicker() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("application/pdf");
try {
startActivityForResult(intent, REQUEST_CODE);
} catch (ActivityNotFoundException e) {
//alert user that file manager not working
Toast.makeText(this, R.string.toast_pick_file_error, Toast.LENGTH_SHORT).show();
}
}
@AfterViews
void afterViews() {
pdfView.setBackgroundColor(Color.LTGRAY);
if (uri != null) {
displayFromUri(uri);
} else {
displayFromAsset(SAMPLE_FILE);
}
setTitle(pdfFileName);
}
private void displayFromAsset(String assetFileName) {
pdfFileName = assetFileName;
pdfView.fromAsset(SAMPLE_FILE)
.defaultPage(pageNumber)
.onPageChange(this)
.enableAnnotationRendering(true)
.onLoad(this)
.scrollHandle(new DefaultScrollHandle(this))
.spacing(10) // in dp
.onPageError(this)
.pageFitPolicy(FitPolicy.BOTH)
.load();
}
private void displayFromUri(Uri uri) {
pdfFileName = getFileName(uri);
pdfView.fromUri(uri)
.defaultPage(pageNumber)
.onPageChange(this)
.enableAnnotationRendering(true)
.onLoad(this)
.scrollHandle(new DefaultScrollHandle(this))
.spacing(10) // in dp
.onPageError(this)
.load();
}
@OnActivityResult(REQUEST_CODE)
public void onResult(int resultCode, Intent intent) {
if (resultCode == RESULT_OK) {
uri = intent.getData();
displayFromUri(uri);
}
}
@Override
public void onPageChanged(int page, int pageCount) {
pageNumber = page;
setTitle(String.format("%s %s / %s", pdfFileName, page + 1, pageCount));
}
public String getFileName(Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} finally {
if (cursor != null) {
cursor.close();
}
}
}
if (result == null) {
result = uri.getLastPathSegment();
}
return result;
}
@Override
public void loadComplete(int nbPages) {
PdfDocument.Meta meta = pdfView.getDocumentMeta();
Log.e(TAG, "title = " + meta.getTitle());
Log.e(TAG, "author = " + meta.getAuthor());
Log.e(TAG, "subject = " + meta.getSubject());
Log.e(TAG, "keywords = " + meta.getKeywords());
Log.e(TAG, "creator = " + meta.getCreator());
Log.e(TAG, "producer = " + meta.getProducer());
Log.e(TAG, "creationDate = " + meta.getCreationDate());
Log.e(TAG, "modDate = " + meta.getModDate());
printBookmarksTree(pdfView.getTableOfContents(), "-");
}
public void printBookmarksTree(List<PdfDocument.Bookmark> tree, String sep) {
for (PdfDocument.Bookmark b : tree) {
Log.e(TAG, String.format("%s %s, p %d", sep, b.getTitle(), b.getPageIdx()));
if (b.hasChildren()) {
printBookmarksTree(b.getChildren(), sep + "-");
}
}
}
/**
* Listener for response to user permission request
*
* @param requestCode Check that permission request code matches
* @param permissions Permissions that requested
* @param grantResults Whether permissions granted
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
@NonNull int[] grantResults) {
if (requestCode == PERMISSION_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
launchPicker();
}
}
}
@Override
public void onPageError(int page, Throwable t) {
Log.e(TAG, "Cannot load page " + page);
}
}
### 参照
| いいえ | 林 |
|---|---|
| 1. | 参照 例 |
| 2. | 続きを読む |
| 3. | 直接ダウンロード |
2.PdfiumAndroid
AndroidPdfViewer の同じ作成者である bartesk は、オリジナル リポジトリ から PdfiumAndroid をフォークし、保守および追加を行っています。 ドキュメントも同様に。
オリジナルの PdfiumAndroid はメンテナンスされていません。
そのため、フォークされたバージョン にはドキュメントがあり、積極的にメンテナンスされています。
彼は人気のある AndroidPdfViewer で使用するためにそれをフォークしました。
ただし、独立して使用することもできます。
まず、依存関係として追加する必要があります。
implementation 'com.github.barteksc:pdfium-android:1.8.2'
次に、簡単な例を示します。
void openPdf() {
ImageView iv = (ImageView) findViewById(R.id.imageView);
ParcelFileDescriptor fd = ...;
int pageNum = 0;
PdfiumCore pdfiumCore = new PdfiumCore(context);
try {
PdfDocument pdfDocument = pdfiumCore.newDocument(fd);
pdfiumCore.openPage(pdfDocument, pageNum);
int width = pdfiumCore.getPageWidthPoint(pdfDocument, pageNum);
int height = pdfiumCore.getPageHeightPoint(pdfDocument, pageNum);
// ARGB_8888 - best quality, high memory usage, higher possibility of OutOfMemoryError
// RGB_565 - little worse quality, twice less memory usage
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.RGB_565);
pdfiumCore.renderPageBitmap(pdfDocument, bitmap, pageNum, 0, 0,
width, height);
//if you need to render annotations and form fields, you can use
//the same method above adding 'true' as last param
iv.setImageBitmap(bitmap);
printInfo(pdfiumCore, pdfDocument);
pdfiumCore.closeDocument(pdfDocument); // important!
} catch(IOException ex) {
ex.printStackTrace();
}
}
public void printInfo(PdfiumCore core, PdfDocument doc) {
PdfDocument.Meta meta = core.getDocumentMeta(doc);
Log.e(TAG, "title = " + meta.getTitle());
Log.e(TAG, "author = " + meta.getAuthor());
Log.e(TAG, "subject = " + meta.getSubject());
Log.e(TAG, "keywords = " + meta.getKeywords());
Log.e(TAG, "creator = " + meta.getCreator());
Log.e(TAG, "producer = " + meta.getProducer());
Log.e(TAG, "creationDate = " + meta.getCreationDate());
Log.e(TAG, "modDate = " + meta.getModDate());
printBookmarksTree(core.getTableOfContents(doc), "-");
}
public void printBookmarksTree(List<PdfDocument.Bookmark> tree, String sep) {
for (PdfDocument.Bookmark b : tree) {
Log.e(TAG, String.format("%s %s, p %d", sep, b.getTitle(), b.getPageIdx()));
if (b.hasChildren()) {
printBookmarksTree(b.getChildren(), sep + "-");
}
}
}
| 見る | ダウンロード |
|---|---|
| 表示 | 直接ダウンロード |
3. PdfBox-Android
PdfBox-Android は、Android で使用できるように Apache の PdfBox ライブラリを移植したものです。 親ライブラリにあるほとんどの機能は、PdfBox-Android にすでに実装されています。
PdfBox-Android のすべての機能を利用するには、Android API 19 以降が必要です。
PdfBox-Android は、PDF ドキュメントのレンダリングを可能にするもう 1 つのライブラリです。 これは Tom Roush によって書かれ、複数の寄稿者がいます。
PdfBox-Android プロジェクトのメイン コードは、こちら にある Apache 2.0 ライセンスに基づいてライセンスされています。
このライブラリは 4 年以上存在していますが、今でも定期的に更新されています。
PdfBox-Androidのインストール
PdfBox-Android のインストール方法は次のとおりです。
アプリレベルの build.gradle に移動し、実装ステートメントを追加します。
dependencies {
implementation 'com.tom-roush:pdfbox-android:1.8.10.3'
}
最新バージョンはこちらでご確認いただけます。
Maven を使用している場合:
<dependency>
<groupId>com.tom_roush</groupId>
<artifactId>pdfbox-android</artifactId>
<version>1.8.10.0</version>
<type>pom</type>
</dependency>
PDFBox を呼び出す前に、ライブラリのリソース ローダーを初期化することを強くお勧めします。 PDFBox メソッドを呼び出す前に次の行を追加します。
PDFBoxResourceLoader.init(getApplicationContext());
### 例
以下に例を示します。
MainActivity.java
public class MainActivity extends Activity {
File root;
AssetManager assetManager;
Bitmap pageImage;
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
setup();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
/**
* Initializes variables used for convenience
*/
private void setup() {
// Enable Android asset loading
PDFBoxResourceLoader.init(getApplicationContext());
// Find the root of the external storage.
root = getApplicationContext().getCacheDir();
assetManager = getAssets();
tv = (TextView) findViewById(R.id.statusTextView);
}
/**
* Creates a new PDF from scratch and saves it to a file
*/
public void createPdf(View v) {
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
// Create a new font object selecting one of the PDF base fonts
PDFont font = PDType1Font.HELVETICA;
// Or a custom font
// try
// {
// // Replace MyFontFile with the path to the asset font you'd like to use.
// // Or use LiberationSans "com/tom_roush/pdfbox/resources/ttf/LiberationSans-Regular.ttf"
// font = PDType0Font.load(document, assetManager.open("MyFontFile.TTF"));
// }
// catch (IOException e)
// {
// Log.e("PdfBox-Android-Sample", "Could not load font", e);
// }
PDPageContentStream contentStream;
try {
// Define a content stream for adding to the PDF
contentStream = new PDPageContentStream(document, page);
// Write Hello World in blue text
contentStream.beginText();
contentStream.setNonStrokingColor(15, 38, 192);
contentStream.setFont(font, 12);
contentStream.newLineAtOffset(100, 700);
contentStream.showText("Hello World");
contentStream.endText();
// Load in the images
InputStream in = assetManager.open("falcon.jpg");
InputStream alpha = assetManager.open("trans.png");
// Draw a green rectangle
contentStream.addRect(5, 500, 100, 100);
contentStream.setNonStrokingColor(0, 255, 125);
contentStream.fill();
// Draw the falcon base image
PDImageXObject ximage = JPEGFactory.createFromStream(document, in);
contentStream.drawImage(ximage, 20, 20);
// Draw the red overlay image
Bitmap alphaImage = BitmapFactory.decodeStream(alpha);
PDImageXObject alphaXimage = LosslessFactory.createFromImage(document, alphaImage);
contentStream.drawImage(alphaXimage, 20, 20 );
// Make sure that the content stream is closed:
contentStream.close();
// Save the final pdf document to a file
String path = root.getAbsolutePath() + "/Created.pdf";
document.save(path);
document.close();
tv.setText("Successfully wrote PDF to " + path);
} catch (IOException e) {
Log.e("PdfBox-Android-Sample", "Exception thrown while creating PDF", e);
}
}
/**
* Loads an existing PDF and renders it to a Bitmap
*/
public void renderFile(View v) {
// Render the page and save it to an image file
try {
// Load in an already created PDF
PDDocument document = PDDocument.load(assetManager.open("Created.pdf"));
// Create a renderer for the document
PDFRenderer renderer = new PDFRenderer(document);
// Render the image to an RGB Bitmap
pageImage = renderer.renderImage(0, 1, ImageType.RGB);
// Save the render result to an image
String path = root.getAbsolutePath() + "/render.jpg";
File renderFile = new File(path);
FileOutputStream fileOut = new FileOutputStream(renderFile);
pageImage.compress(Bitmap.CompressFormat.JPEG, 100, fileOut);
fileOut.close();
tv.setText("Successfully rendered image to " + path);
// Optional: display the render result on screen
displayRenderedImage();
}
catch (IOException e)
{
Log.e("PdfBox-Android-Sample", "Exception thrown while rendering file", e);
}
}
/**
* Fills in a PDF form and saves the result
*/
public void fillForm(View v) {
try {
// Load the document and get the AcroForm
PDDocument document = PDDocument.load(assetManager.open("FormTest.pdf"));
PDDocumentCatalog docCatalog = document.getDocumentCatalog();
PDAcroForm acroForm = docCatalog.getAcroForm();
// Fill the text field
PDTextField field = (PDTextField) acroForm.getField("TextField");
field.setValue("Filled Text Field");
// Optional: don't allow this field to be edited
field.setReadOnly(true);
PDField checkbox = acroForm.getField("Checkbox");
((PDCheckBox) checkbox).check();
PDField radio = acroForm.getField("Radio");
((PDRadioButton)radio).setValue("Second");
PDField listbox = acroForm.getField("ListBox");
List<Integer> listValues = new ArrayList<>();
listValues.add(1);
listValues.add(2);
((PDListBox) listbox).setSelectedOptionsIndex(listValues);
PDField dropdown = acroForm.getField("Dropdown");
((PDComboBox) dropdown).setValue("Hello");
String path = root.getAbsolutePath() + "/FilledForm.pdf";
tv.setText("Saved filled form to " + path);
document.save(path);
document.close();
} catch (IOException e) {
Log.e("PdfBox-Android-Sample", "Exception thrown while filling form fields", e);
}
}
/**
* Strips the text from a PDF and displays the text on screen
*/
public void stripText(View v) {
String parsedText = null;
PDDocument document = null;
try {
document = PDDocument.load(assetManager.open("Hello.pdf"));
} catch(IOException e) {
Log.e("PdfBox-Android-Sample", "Exception thrown while loading document to strip", e);
}
try {
PDFTextStripper pdfStripper = new PDFTextStripper();
pdfStripper.setStartPage(0);
pdfStripper.setEndPage(1);
parsedText = "Parsed text: " + pdfStripper.getText(document);
}
catch (IOException e)
{
Log.e("PdfBox-Android-Sample", "Exception thrown while stripping text", e);
} finally {
try {
if (document != null) document.close();
}
catch (IOException e)
{
Log.e("PdfBox-Android-Sample", "Exception thrown while closing document", e);
}
}
tv.setText(parsedText);
}
/**
* Creates a simple pdf and encrypts it
*/
public void createEncryptedPdf(View v)
{
String path = root.getAbsolutePath() + "/crypt.pdf";
int keyLength = 128; // 128 bit is the highest currently supported
// Limit permissions of those without the password
AccessPermission ap = new AccessPermission();
ap.setCanPrint(false);
// Sets the owner password and user password
StandardProtectionPolicy spp = new StandardProtectionPolicy("12345", "hi", ap);
// Setups up the encryption parameters
spp.setEncryptionKeyLength(keyLength);
spp.setPermissions(ap);
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
PDFont font = PDType1Font.HELVETICA;
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
try
{
PDPageContentStream contentStream = new PDPageContentStream(document, page);
// Write Hello World in blue text
contentStream.beginText();
contentStream.setNonStrokingColor(15, 38, 192);
contentStream.setFont(font, 12);
contentStream.newLineAtOffset(100, 700);
contentStream.showText("Hello World");
contentStream.endText();
contentStream.close();
// Save the final pdf document to a file
document.protect(spp); // Apply the protections to the PDF
document.save(path);
document.close();
tv.setText("Successfully wrote PDF to " + path);
}
catch (IOException e)
{
Log.e("PdfBox-Android-Sample", "Exception thrown while creating PDF for encryption", e);
}
}
/**
* Helper method for drawing the result of renderFile() on screen
*/
private void displayRenderedImage() {
new Thread() {
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
ImageView imageView = (ImageView) findViewById(R.id.renderedImageView);
imageView.setImageBitmap(pageImage);
}
});
}
}.start();
}
}
### 参照
以下から PdfBox-Android を入手します。
| 番号 | 場所 | リンク |
|---|---|---|
| 1. | ギットハブ | 例 |
| 2. | ギットハブ | 直接ダウンロード |
| 3. | ギットハブ | 参照 |
4.PdfViewPager
SD カードに保存されている、アセットとしてリンクされている、またはリモート URL からダウンロードされている PDF ドキュメントをレンダリングできる Android ウィジェット。
このウィジェットは、アクティビティまたはフラグメントに PDF ドキュメントを表示できます。
重要な注意事項: PDFViewPager は PdfRenderer クラスを使用します。API 21 以降でのみ動作します。 詳細については、公式ドキュメント を参照してください。
デモは次のとおりです。

ステップ 1: インストールする
アプリ レベルの build.gradle ファイルに次の実装ステートメントを追加してインストールします。
implementation 'es.voghdev.pdfviewpager:library:1.1.2'
ステップ 2: レイアウトに追加するステップ
PDFViewPager は、宣言的または命令的にページに追加できます。 これを宣言的に追加するには、次のコードをレイアウトに追加します。
<es.voghdev.pdfviewpager.library.PDFViewPager
android:id="@+id/pdfViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
ステップ 3: コードを書く
アセット フォルダーから PDF をロード
PDF ファイルがアセットフォルダーにある場合は、それをキャッシュディレクトリにコピーします。
CopyAsset copyAsset = new CopyAssetThreadImpl(context, new Handler());
copyAsset.copy(asset, new File(getCacheDir(), "sample.pdf").getAbsolutePath(
次のようにロードできます。
<es.voghdev.pdfviewpager.library.PDFViewPager
android:id="@+id/pdfViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:assetFileName="sample.pdf"/>
またはこのように:
pdfViewPager = new PDFViewPager(this, "sample.pdf");
次に、次のように close() を閉じてリソースを解放します。
@Override
protected void onDestroy() {
super.onDestroy();
((PDFPagerAdapter) pdfViewPager.getAdapter()).close();
}
SD カードから PDF をロード
PDF が SD カードにある場合は、SD カード内のファイルの場所を渡して PDFViewPager オブジェクトを作成します。
PDFViewPager pdfViewPager = new PDFViewPager(context, getPdfPathOnSDCard());
protected String getPdfPathOnSDCard() {
File f = new File(getExternalFilesDir("pdf"), "adobe.pdf");
return f.getAbsolutePath();
}
次に、占有されているリソースを解放します。
@Override
protected void onDestroy() {
super.onDestroy();
((PDFPagerAdapter) pdfViewPager.getAdapter()).close();
}
リモート ソースから PDF をロードする方法
まず、Android マニフェストに次の権限を追加します。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
次に、アクティビティまたはフラグメントに DownloadFile.Listener を実装させます。
public class RemotePDFActivity extends AppCompatActivity implements DownloadFile.Listener {
次に、RemotePDFViewPager オブジェクトを作成します。
String url = "http://www.cals.uidaho.edu/edComm/curricula/CustRel_curriculum/content/sample.pdf";
RemotePDFViewPager remotePDFViewPager =
new RemotePDFViewPager(context, url, this);
次に、イベントを処理します。
@Override
public void onSuccess(String url, String destinationPath) {
// That's the positive case. PDF Download went fine
adapter = new PDFPagerAdapter(this, "AdobeXMLFormsSamples.pdf");
remotePDFViewPager.setAdapter(adapter);
setContentView(remotePDFViewPager);
}
@Override
public void onFailure(Exception e) {
// This will be called if download fails
}
@Override
public void onProgressUpdate(int progress, int total) {
// You will get download progress here
// Always on UI Thread so feel free to update your views here
}
そしてもちろんアダプターを閉じます。
@Override
protected void onDestroy() {
super.onDestroy();
adapter.close();
}
完全な例は以下でご覧ください。
### 参照
| 番号 | リンク |
|---|---|
| 1. | 参照 例 |
| 2. | 読む 詳細 |
| 3. | フォロー ライブラリ著者 |