android studio 無法自動較正錯誤及語法提示
Android Studio 無法自動較正錯誤及語法提示
原因很簡單:
在Android Studio 的 File/Power Save Mode
的勾拿掉即可.
Android Studio 無法自動較正錯誤及語法提示
原因很簡單:
在Android Studio 的 File/Power Save Mode
的勾拿掉即可.
有兩個問題
顯卡不支援opengl
無線網卡, 速率只能跑1M左右
以上兩個問題都是驅動的問題, 其中無線網卡用最新的驅動,
反而有問題, 必須改用較舊的驅動, 但在設備管理員中, 無法讓你
安裝較舊的驅動, 後來改用驅動人生安裝, 才解決問題.
而顯卡驅動雖然較新, 但同樣在驅動人生中才能安裝.
2016/06/14 更新
後來重新安裝,發現驅動人生也無法安裝無線網卡了。
找到資料,要先刪除C:\Windows\System32\DriverStore\FileRepository
netbc63.inf_x86開頭的一個文件夾,才能安裝自訂的驅動。
要安裝以下的檔案:
sp45524.exe
2016/8/12
顯卡部分要安裝 ati driver 64bit
openGL 才能正確執行
修改以下例子:
https://code.google.com/archive/p/sjxslx/
https://github.com/davidpelfree/sjxlsx
因為我是使用在android上, 而以上兩個範例都是java的例子
執行時會一直出現com.bea.xml.stream.MXParserFactory找不到的錯誤
edu.usf.cutr.javax.xml.stream.FactoryConfigurationError: Provider om.bea.xml.stream.MXParserFactory not found
但這個class事實上存在 stax-1.2.0.jar 中, 無論在gradle中, 使用
compile file 或 provided file 的方法或直接加到 libs 都無法找到
此class, 我甚至把com.bea.xml.stream.MXParserFactory
直接抽出, 重新打包到stax-api-android-1.0-2.jar這個原來就存
在且可使用的 jar 裡也一樣找不到.
找到source code 想要改寫MXParserFactory但發現裡面又牽扯太廣太深,
不好改寫
修改 XMLInputFactory 成 MyXMLInputFactory, find函數,裡面
第二個參數 由com.bea.xml.stream.MXParserFactory 改成
edu.usf.cutr.javax.xml.stream.XMLEventFactory
如下:
MyFactoryFinder.find("edu.usf.cutr.javax.xml.stream.XMLInputFactory", "edu.usf.cutr.javax.xml.stream.XMLEventFactory");
錯誤訊息變成:
Provider edu.usf.cutr.javax.xml.stream.XMLEventFactory could not be instantiated:
可見已經找到了, 只是無法instantiated
可見只有com.bea.xml.stream 開頭的class找不到, 不知是否一樣要改成
edu.usf.cutr才可以
(見 http://save-coco.blogspot.tw/2016/05/javaxxmlstreamandroidlibraries.html)
另外在FactoryFinder中有使用到"META-INF/services/", 可能因為
android 不會把 META-INF 內的文件安裝到apk, 也會出問題
(update:確定不是此原因)
所以總之放棄此作法
https://pan.baidu.com/s/1o7HoY3w
update:20160605
經過幾天的努力, 終於可以成功讀取了.
provider com.bea.xml.stream.MXParserFactory 找不到的問題終於解決了
參考 http://stackoverflow.com/questions/30968735/using-com-bea-xml-stream-package-on-android
原文
I believe the main issue here is that Apache POI depends on JSR173
Streaming API for XML, which depends on the platform (in our case Android)
being able to provide an implementation and underlying XML parsing provider. Android doesn't support JSR173, so it can't find a provider - com.bea.xml.stream.EventFactory is the default provider, and it can't even find that one (see JAXB marshalling exception javax.xml.stream.FactoryConfigurationError running with Java 5 for more details on this topic).
Aalto is an open-source JSR173 provider, so you should be able to use this in place of the BEA implementation (com.bea.xml.stream.EventFactory). The Aalto archive (JAR file) includes the necessary registration (under META-INF/services/javax.xml.stream.XMLInputFactory file, that points to the Aalto class com.fasterxml.aalto.stax.InputFactoryImpl) that should allow a Java platform to recognize it as a JSR173 implementation. As a result, you should no longer get the edu.usf.cutr.javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.EventFactory not found error, because Android should recognize that Aalto is an available provider, and use Aalto instead.
大意是說:Apache POI 必須依賴JSR173 Streaming API for XML 作為
provider , 但 android 不支援 JSR173 , 所以才會出現找不到作為 provider的 com.bea.xml.stream.EventFactory .而必須改用Aalto , 而且
android 支援 Aalto .
所以在android想要讀取xlsx資料, 必須更改使用的provider, 將
stax-api中stax-api-1.0-2.jar 換成Aalto 的 aalto-xml-android-0.9.8.jar
Aalto有幾個不同的 class
com.fasterxml.aalto.stax.EventFactoryImpl
com.fasterxml.aalto.stax.InputFactoryImpl
com.fasterxml.aalto.stax.OutputFactoryImpl
必須查看原程式碼傳回那一個物件來決定採用那個 provider
所以要在android 讀 excel 的重點就是
1.必須修改原始碼, 更改 provider
2.還有必須將 javax.xml.stream 更名
要打包的資料夾(D:\stax-api-android-1.0-2)內有如下的子資
料夾, 內含有*.class的檔案
2016/05/28 上午 11:09
執行 generate_android_jars.bat
, 在output內的libraries即可用來供javax.xml.stream.*
改成 edu.usf.cutr.javax.xml.stream.*
:XMLStreamWriter
is in thejavax.xml.stream.*
package. This package is not included in the default Android build. You can use it, but you have to repackage it in your app.
Description of your problem and a guide on how to repackage javax.* packages:http://code.google.com/p/dalvik/wiki/JavaxPackagesIf you don't want to repackageXMLStreamWriter
in your app, try usingXmlSerializer
which is included in Android. Excellent example right here on SO: Writing XML on Android
ArrayUtils
int n = ArrayUtils.indexOf(displayItem, "abc");
傳回String[] displayItem中含有字串"abc"的位置
if ( ArrayUtils.contains( displayItem, "abc" ) ) {
// Do some stuff.
}
String[] displayItem中含有字串"abc"則傳回真值
FileUtils
FileUtils.cleanDirectory("/abc");
清除整個資料夾及子資料夾, 但不含資料夾abc本身
FileUtils.deleteDirectory("/abc");
清除整個資料夾及子資料夾, 含資料夾abc本身
File f = new File("/sd/abc.txt");
String str = FileUtils.readFileToString(f, code);
將文字檔案f整個讀入一個字串內, code是該檔案的編碼格式(utf-8,big5...)
FileUtils.writeStringToFile(f, fileContent, "big5");
將字串fileContent寫出到f
File file = new File("c:/test.txt");
List lines = FileUtils.readLines(file, "UTF-8");
將test.txt一行一行讀入List內
File src = new File("src.txt");
File dest = new File("dest.txt");
FileUtils.copyFile(src, dest);
複製檔案並重命名
File srcfile = new File("c:\\Test.java");
File destDir = new File("D:\\");
FileUtils.copyFileToDirectory(srcfile, destDir);
複製檔案到目錄下
InputStream in = new
URL("http://www.baidu.com/img/baidu_logo.gif").openStream();
byte [] gif = IOUtils.toByteArray(in);
//IOUtils.write(gif,new FileOutputStream(new File("c:/test.gif")));
FileUtils.writeByteArrayToFile(new File("c:/test.gif"),gif);
IOUtils.closeQuietly(in);
下载文件到本地
URL url = new URL("http://www.163.com");
File file = new File("c:\\163.html");
FileUtils.copyURLToFile(url, file);
網頁保存成本地文件
FilenameUtils
String ext = FilenameUtils.getExtension(file.toString());
取得副檔名
String baseName = FilenameUtils.getBaseName(f.toString());
取得主檔名(不含副檔名及小數點)
IOUtils
將inputStream轉成字串
InputStream in = new URL( "http://laoyu.info" ).openStream();
try {
System.out.println( IOUtils.toString( in ) );
} finally {
IOUtils.closeQuietly(in);
}
Read more...
筆電獨立顯卡是筆電最容易故障的一個地方, 很多可以過電, 但沒畫面,
的筆電, 有很大的比例是顯卡故障, 而原因有可能是焊鍚因長時間高溫,
造成接觸不良.
通常的維修方法是用重新植鍚球的方式, 但這樣做技術層次比較高, 而且
需要一些專業的設備.
於是有些人就想到一個方法, 就是用熱風槍直接對顯卡晶片加熱, 直到焊鍚
可以熔化的溫度, 於是就可以修好這個顯卡, 但事實上這個做法, 只是治標
不治本, 過個幾天, 也許一星期, 可能又會因為高溫或熱脹冷縮的原因而再
次故障.
我有兩台筆電, 都是因為這個原因故障, 在網路上買一個便宜的工業用的熱風
槍, 只花了八百元左右, 而且還可控制溫度, 並顯示溫度. 看來頗物超所值.
上網尋找一些文章, 大概知道作法.
首先拆下筆電, 取出主機板, 準備一張鍚鉑紙, 中間剪出一個正方形的洞,
用鍚鉑紙蓋住主機板的其他部分, 只露出顯卡晶片.
因為必須控制溫度, 熱風槍顯示的溫度, 和顯卡晶片實際受熱的溫度, 一定
有差距, 因此我拿一個廚房用的溫度計, 最大溫度可顯示250度, 這個是在一
般五金雜貨店買的. 先用熱風槍對著溫度計吹, 得知熱風槍顯示380度時,
貼近溫度計, 大約是220度, 而熱風槍顯示480度時, 貼近溫度計, 大約是
270度. (估計值, 因為溫度計最多只顯示到250度)
根據查來的資料, 先用熱風槍對著顯示晶片吹(注意這是一打開熱風槍就開
始吹, 不是等熱風槍達到380度時才吹), 一直到溫度到達380度為止, 然後
控制溫度保持在380度左右(晶片實際受熱溫度220度), 從開始吹的時間到大約
二到三分鐘為止(我大約吹了二分半鐘), 然後調高溫度, 讓熱風槍跑到480
度(實際受熱溫度270度), 大約再吹一分鐘, 所以一共吹了三分半鐘, 然後
移開熱風槍, 慢慢等待冷卻.
這樣的方法, 兩台筆電均成功修復, 目前其中一台已運作二星期. 另一台還沒
使用.
有兩個方法
1. recreate()
不是完全重新啟動, 再次啟動時, 會保留上一次啟動的SaveInstanceState
2.
Intent intent = getIntent(); finish(); startActivity(intent);
用這種方法, 不會保留SaveInstanceStateRead more...
個人感覺的使用時機:
1.當Activity徹底運行起來之後回調onPostCreate方法,如果是比較需要時
間的作業, 例如開啟app後,立即copy一些檔案到某處, 這個copy的動作,
好像寫在onPostCreate比較好, 如果寫在onCreate, 有時似乎不執行(個人印象
, 不知是否正確).
2.在onCreate 建立一個 Thread :
indexThread = new IndexThread();
indexThread.start();
當indexThread啟動以後, indexThread.handler會在一段時間才能建立, 在之
前會是null, 如果是null, 則對indexThread的所有操作都會失敗, 所以我加了
一個空迴圈判斷, 當indexThread.handler不是null的時候才往下執行.
while (indexThread.handler == null) {
}
3.另外如果要用到 savedInstanceState, 除了onCreate之外, 也只
有onPostCreate有提供savedInstanceState這個參數, onStart沒有.
因為必須在/data/data內刪除設定檔的目錄, 以前都是直接在genymotion內的模擬
器, 直接刪除, 但換到6.0以後, 不知為何這個目錄無權讀取, 想到一個變通的方法
直接在virtualbox中開啟虛擬機
用adb連到虛擬機
adb connect 192.168.56.101
直接到shell操作
adb shell
給序全部權限
chmod 777 /data/data
查看是否成功更改
ls /data/data/ -ld
更改成功, 但回到genymotion中開啟虛擬機, 結果權限又被改回無法讀取的狀態
再想一個方法, 這次不改權限, 改直接在adb shell內刪除/data/data/內的檔案
刪除完成, 而且在genymotion內的模擬器內, 該檔案也消失不見了.
後來又發現一個比較好的方法
在android studio 或 eclipse 中的 Android device monitor 中的file explore
可以用 把/data/data內的檔案下載到pc端檢視, 也可以刪除, 但有時會失敗, 如果失敗
的時候, 在Tool/Android/Enable ADB Integration 把打勾的地方拿掉, 就可正常下載.
update 20160619
原來用 adb 一直無法連到genymotion的模擬器, 會出現
ADB server didn't ACK * failed to start daemon *
的錯誤.
後來發現使用 genymotion 目錄下的 adb 就可連上
C:\Program Files\Genymobile\Genymotion\tools>adb devices
會出現一個 ip
C:\Program Files\Genymobile\Genymotion\tools>adb connect ip
update 20161011
讀取未root手機, data/data內資料夾的兩個方法
http://stackoverflow.com/questions/13006315/how-to-access-data-data-folder-in-android-device
If the application is debuggable you can use the run-as command in adb shell adb shell run-as com.your.packagename cp /data/data/com.your.packagename/ Alternatively you can use Android's backup function. adb backup -noapk com.your.packagename You will now be prompted to 'unlock your device and confirm the backup operation'. It's best NOT to provide a password, otherwise it becomes more difficult to read the data. Just click on 'backup my data'. The resulting 'backup.ab' file on your computer contains all application data in android backup format. Basically it's a compressed tar file. This page explains how you can use OpenSSL's zlib command to uncompress it. You can use the adb restore backup.db command to restore the backup.Read more...
顯示卡的問題, 必須支援openGL 2.0以上, 而顯卡不支援openGL有可能是驅動程式未更新, 或驅動有問題.
另一個原因是virtualbox版本的問題, 試著更新到最新版或還原到較舊的版本, 都有可能可以解決問題
如果想查看錯誤的更多細節, 查看:
C:\Users\使用者名稱\AppData\Local\Genymobile\genymotion.log
android 6.0 採對個別app的權限管理方式, 如果使用者未開放權限, 則app訪問sdcard的功能將出問題
所以如果使用者未開放權限的話, 可在app中要求使用者開放
在activity中的oncreate寫如下程式碼:
boolean hasPermission = (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermission) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_STORAGE);
}
上面的程式碼, 會引發以下事件
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case REQUEST_WRITE_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
//如果同意, 則重啟acitvity, 正常執行
recreate();
} else {
//如果不同意, 則再次請求, 若使用者同意考慮, 則再重啟activity, 會再訽問一次
TextApp.YesNoListener ynListener=new TextApp.YesNoListener() {
@Override
public void onYes() {
recreate();
}
//若不同意再考慮, 則退出程序
@Override
public void onNo() {
finish();
}
};
TextApp.showOkCancelDialog("The app was not allowed to write to your storage. Hence, it cannot function properly. Do you want to consider granting it this permission again?",this,ynListener);
}
}
}
}
TextApp中顯示訽問視窗的函數
public static void showOkCancelDialog(String msg, Context _ac,
YesNoListener _yesnoListener) {
final YesNoListener yesnoListener = _yesnoListener;
AlertDialog.Builder ssa = new AlertDialog.Builder(_ac);
ssa.setMessage(msg);
ssa.setIcon(R.drawable.ic_noti_dict);
ssa.setPositiveButton(
getContext().getResources().getString(R.string.strOk),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
yesnoListener.onYes();
}
}).setNegativeButton(
getContext().getResources().getString(R.string.strCancel),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.out.println("cancel");
yesnoListener.onNo();
// AnswerIsOK = false; }
});
AlertDialog alert = ssa.create();
alert.show();
}
個人感覺出現這個問題, 大部分是ram的原因
在dos命令列, project的根目錄
下gradlew assembleDebug --info命令
可以見到更多原因
All input files are considered out-of-date for increm
ental task ':app:transformClassesWithDexForDebug'.
Allocated dexExecutorService of size 4
To run dex in process, the Gradle daemon needs a larg
er heap.
It currently has approximately 989 MB.
For faster builds, increase the maximum heap size for
the Gradle daemon to more than 3072 MB.
To do this set org.gradle.jvmargs=-Xmx3072M in the pr
oject gradle.properties.
For more information see https://docs.gradle.org/curr
ent/userguide/build_environment.html
Dexing out-of-process.
Starting process 'command 'C:\Program Files\Java\jdk1
.8.0_91\bin\java.exe''. Working directory: D:\Android
\Studio\docSearcher\app Command: C:\Program Files\Jav
a\jdk1.8.0_91\bin\java.exe -Djava.awt.headless=true -
Xmx2g -Dfile.encoding=UTF-8 -Duser.country=TW -Duser.
language=zh -Duser.variant -cp C:\Users\mayr\Android\
sdk\build-tools\23.0.3\lib\dx.jar com.android.dx.comm
and.Main --dex --verbose --num-threads=4 --multi-dex
--main-dex-list D:\Android\Studio\docSearcher\app\bui
ld\intermediates\multi-dex\debug\maindexlist.txt --ou
tput D:\Android\Studio\docSearcher\app\build\intermed
iates\transforms\dex\debug\folders\1000\1f\main D:\An
droid\Studio\docSearcher\app\build\intermediates\tran
sforms\jarMerging\debug\jars\1\1f\combined.jar
Successfully started process 'command 'C:\Program Fil
es\Java\jdk1.8.0_91\bin\java.exe''
Error occurred during initialization of VM
Could not reserve enough space for 2097152KB object h
eap
:app:transformClassesWithDexForDebug FAILED
:app:transformClassesWithDexForDebug (Thread[Daemon w
orker,5,main]) completed. Took 0.218 secs.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:transformClassesWithD
exForDebug'.
> com.android.build.api.transform.TransformException:
com.android.ide.common.process.ProcessException: jav
a.util.concurrent.ExecutionException: com.android.ide
.common.process.ProcessException: org.gradle.process.
internal.ExecException: Process 'command 'C:\Program
Files\Java\jdk1.8.0_91\bin\java.exe'' finished with n
on-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace.
Run with -
-debug
option to get more log output.
BUILD FAILED
上面紅字部分就是原因所在
我在build.gradle為dex保留2G的heapsize:
dexOptions {
javaMaxHeapSize "2g"}
結果ram 不夠, 所以造成java.exe finished with n on-zero exit value 1的錯誤
參考了一些資料:
android studio希望你能在電腦上不安裝gradle的情況下,依然使用gradle管理android項目,因此通過AS創建的每個項目都會內嵌一個gradle wrapper,作用是檢查你當前的共工作環境是否安裝了創建本項目時所用的gradle版本。
如果沒有,它會自動下載相應的gradle放在~/.gradle/wrapper.目錄下。這樣當你在你的項目裡使用gradle時,可以通過gradlw命令使用當前項目環境的gradle版本,而不受環境變量的影響。
本來想移植apache poi 到 android, 但遇到很多困難, 所以放棄,
但記錄如下:(update :經過努力, 終於找到了方向, 見下說明)
apache poi 移植到 android 的問題
however it will not work straighforwardly because xmlbeans jar in
maven is defective and contains duplicates of classes, [...] it is
easier just to prepare jars once and put them into libs directory
(as described above)
大意是說xmlbeans 包含重覆的class, 在android 是不允許的
以下這兩個連結有實作, 但大概試了一下, 不是很順利, 所以放
棄, 最大的問題是noclassdeffounderror無所不在, 還有jar重覆的
問題, 用到android不支持的jdk等
Reading XLSX on Android 4
不同msoffice格式所用的的poi jar
POIFS | OLE2 Filesystem | poi |
HPSF | OLE2 Property Sets | poi |
HSSF | Excel XLS | poi |
HSLF | PowerPoint PPT | poi-scratchpad |
HWPF | Word DOC | poi-scratchpad |
HDGF | Visio VSD | poi-scratchpad |
HPBF | Publisher PUB | poi-scratchpad |
HSMF | Outlook MSG | poi-scratchpad |
XSSF | Excel XLSX | poi-ooxml |
XSLF | PowerPoint PPTX | poi-ooxml |
XWPF | Word DOCX | poi-ooxml |
OpenXML4J | OOXML | poi-ooxml-schemas, ooxml-schemas |
1. provider 的問題
2. javax.xml.stream , android不支援的問題
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile project(':library')
compile files('libs/dropbox-android-sdk-1.6.3.jar')
compile files('libs/json_simple-1.1.jar')
compile files('libs/ksoap2-android-assembly-2.4-jar-with-dependencies.jar')
compile project(':lucene-analyzers-common-4.7.2')
compile project(':lucene-core-4.7.2')
這個問題, 好像大都是超過65536個函數所引起, 所以只要想辦法減少函數數目或在build.gradle中宣告
multiDexEnabled true 即可解決
Read more...android { compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig { applicationId "com.myapplication" minSdkVersion 16 targetSdkVersion 23 versionCode 1 versionName "1.0" multiDexEnabled true } ....
You most likely have a duplicate dependency in one of your compile project
極可能是兩個以上的library重覆使用在一個project內
在gradle中將
"compile fileTree(dir: 'libs', include: ['*.jar'])"
改成
"provided fileTree(dir: 'libs', include: ['*.jar'])".
可以解決問題
發生Android java.exe finished with non-zero exit value 1的問題, 很多人提到很有可能是ram的問題, 或是clean project, rebuild project, 或是重開系統, 可解決, 但我在處理 poi 轉到 android 時發生此一問題, 並且有一大串訊息如下:
在dos視窗project的根目錄下 執行 gradlew assembleDebug --info
可見以下訊息:
java.exe
Ill-advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.
This is often due to inadvertently including a core library file
in your application's project, when using an IDE (such as
Eclipse). If you are sure you're not intentionally defining a
core class, then this is the most likely explanation of what's
going on.
However, you might actually be trying to define a class in a core
namespace, the source of which you may have taken, for example,
from a non-Android virtual machine project. This will most
assuredly not work. At a minimum, it jeopardizes the
compatibility of your app with future versions of the platform.
It is also often of questionable legality.
If you really intend to build a core library -- which is only
appropriate as part of creating a full virtual machine
distribution, as opposed to compiling an application -- then use
the "--core-library" option to suppress this error message.
If you go ahead and use "--core-library" but are in fact
building an application, then be forewarned that your application
will still fail to build or run, at some point. Please be
prepared for angry customers who find, for example, that your
application ceases to function once they upgrade their operating
system. You will be to blame for this problem.
If you are legitimately using some code that happens to be in a
core package, then the easiest safe alternative you have is to
repackage that code. That is, move the classes in question into
your own package namespace. This means that they will never be in
conflict with core system classes. JarJar is a tool that may help
you in this endeavor. If you find that you cannot do this, then
that is an indication that the path you are on will ultimately
lead to pain, suffering, grief, and lamentation.
查找了一下原因, 原文如下:
Dalvik JVM does not support the entire API of Oracle JDK. I think javax.* packages aren't available to Android. For example there's no AWT or Swing or Graphics2D of Java on Android.
From the error, it looks like you app is using this Class:http://docs.oracle.com/javase/7/docs/api/javax/xml/namespace/QName.html
This shouldn't happen If you set up your IDE to use Android SDK instead of JDK.
大意是因為Android並不支持全部JDK的api, 例如 AWT, Swing, 還有部分javax開頭的api 等, 所以以上的訊息就是因為poi用到了這些不支持android的api,
加上"--core-library"的參數, 可避免出現以上訊息
static {
try {
... your init code here
} catch (Throwable t) {
LOG.error("Failure during static initialization", t);
throw t;
}
}
出現 NoClassDefFoundError : org.apache.tika.parse.xml.DcXMLParser
org.apache.tika.parse.xml.DcXMLParser明明是存在的, 所以深入追踪原始碼:
EpubParser epubParser = null; if (type.equals("epub")) {
//NoClassDefFoundError出現在下面這一行
epubParser = new EpubParser();
epubParser.parse(inputstream, handler, metadata, pcontext);
}
找到 EpubParser 的原始碼:
public class EpubParser extends AbstractParser { private static final long serialVersionUID = 215176772484050550L; private static final SetSUPPORTED_TYPES = Collections.unmodifiableSet(new HashSet(Arrays.asList
(new MediaType[]{MediaType.application("epub+zip"),MediaType.application("x-ibooks+zip")})));
//DcXMLParser 找不到 private Parser meta = new DcXMLParser();private Parser content = new EpubContentParser(); public EpubParser() { } public Parser getMetaParser() { return this.meta; } public void setMetaParser(Parser meta) { this.meta = meta; } public Parser getContentParser() { return this.content; } public void setContentParser(Parser content) { this.content = content; } public SetgetSupportedTypes(ParseContext context) { // 在這一行出錯, 但這是最後一行返回值, 可見不是這一行的原因, 而是上//方定義 private Parser meta = new DcXMLParser();時出錯 return SUPPORTED_TYPES; }找出 DcXMLParser 的原始碼:
原來是下面有幾個import的元件未加入library中,
將未加入的部分加入就解決了
import org.apache.tika.metadata.Metadata; import org.apache.tika.metadata.Property; import org.apache.tika.metadata.TikaCoreProperties; import org.apache.tika.parser.ParseContext; import org.apache.tika.parser.xml.ElementMetadataHandler; import org.apache.tika.parser.xml.XMLParser; import org.apache.tika.sax.TeeContentHandler; import org.xml.sax.ContentHandler; public class DcXMLParser extends XMLParser { private static final long serialVersionUID = 4905318835463880819L; public DcXMLParser() { } private static ContentHandler getDublinCoreHandler(Metadata metadata, Property property, String element) { return new ElementMetadataHandler("http://purl.org/dc/elements/1.1/", element, metadata, property); } protected ContentHandler getContentHandler(ContentHandler handler, Metadata metadata, ParseContext context) { return new TeeContentHandler(new ContentHandler[]{super.getContentHandler(handler, metadata, context), getDublinCoreHandler(metadata, TikaCoreProperties.TITLE, "title"), getDublinCoreHandler(metadata, TikaCoreProperties.KEYWORDS, "subject"), getDublinCoreHandler(metadata, TikaCoreProperties.CREATOR, "creator"), getDublinCoreHandler(metadata, TikaCoreProperties.DESCRIPTION, "description"), getDublinCoreHandler(metadata, TikaCoreProperties.PUBLISHER, "publisher"), getDublinCoreHandler(metadata, TikaCoreProperties.CONTRIBUTOR, "contributor"), getDublinCoreHandler(metadata, TikaCoreProperties.CREATED, "date"), getDublinCoreHandler(metadata, TikaCoreProperties.TYPE, "type"), getDublinCoreHandler(metadata, TikaCoreProperties.FORMAT, "format"), getDublinCoreHandler(metadata, TikaCoreProperties.IDENTIFIER, "identifier"), getDublinCoreHandler(metadata, TikaCoreProperties.LANGUAGE, "language"), getDublinCoreHandler(metadata, TikaCoreProperties.RIGHTS, "rights")}); } }
2016/06/01 update
令天又遇到一個 NoClassDefFoundError 的問題
基本上與昨天遇到的問題差不多, 同樣是 import 的地方沒把 class 加進來而出問題.
但今天的問題, 即使把 import 的地方的 class 加進來, 一樣報錯.
報 NoClassDefFoundError 的錯誤的是這個 org.apache.tika.io.TikaInputStream class追踪TikaInputStream 的原始碼:
package org.apache.tika.io; //以下三個 import 的class 都加入了, 仍然報錯 import org.apache.tika.io.TaggedInputStream; import org.apache.tika.io.TemporaryResources; import org.apache.tika.metadata.Metadata; //原來問題出在 TaggedInputStream , 因為 TikaInputStream 是繼承 TaggedInputStream//所以要把 TaggedInputStream 的原始碼也挖出來看public class TikaInputStream extends TaggedInputStream { private static final int BLOB_SIZE_THRESHOLD = 1048576; private Path path; private final TemporaryResources tmp; private long length; private long position = 0L;//TikaInputStream 以下原始碼省略...
}TaggedInputStream 的原始碼:
//把以下兩個 class 加入(ProxyInputStream及TaggedIOException), 就解決了,//所以不止看出問題的 class, 如果它繼承自別的 class , 連父類的 class//也要查看是否有import 的 class 未加入.import org.apache.tika.io.ProxyInputStream; import org.apache.tika.io.TaggedIOException; public class TaggedInputStream extends ProxyInputStream { private final Serializable tag = UUID.randomUUID(); public TaggedInputStream(InputStream proxy) { super(proxy); }還有一種情況:所有的 import 都己加入 library 中, 但在程碼中, 卻直接引用
class 如下面的 org.apache.xmlbeans.SchemaComponent.Ref 也要加進來public void setContainerFieldRef(org.apache.xmlbeans.SchemaComponent.Ref ref) { this.assertUnresolved(); this._containerFieldRef = ref; this._containerFieldCode = 0; }
http://www.findjar.com/
輸入 class的全名
例如 org.apache.poi.xwpf.usermodel.XWPFDocument
按下 右方的jar/class search, 會出現你查的class
點按進入, 即可見查找的jar名
mString="abcdefghijk"
mString.subString(0,5) : 並不是從第一個取到第六個, 而是從第一個取到第五個
結果:abcde
那如果要接下去取fgh, 一般會以為是mString.subString(6,9)
, 但不對, 應該是mString.subString(5,8)
想在spinner開啟時,自動選定其中一個項目,但如果直接setSelection, 可能不會有作用,必須放到post內才可
private Spinner sort_spinner;
sort_spinner = (Spinner) layout.findViewById(R.id.sort_item);
//如果直接setSelection, 可能不會有作用
//sort_spinner.setSelection(sortField);
//必須放到post內才會有作用
sort_spinner.post(new Runnable() {
public void run() {
sort_spinner.setSelection(sortField);
}
});
方法一
推薦此種方法
public class BlockScrollView extends ScrollView {
//private boolean shouldWindowFocusWait;
public BlockScrollView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public BlockScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BlockScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
// true if we can scroll (not locked)
// false if we cannot scroll (locked)
private boolean mScrollable = true;
public void setScrollingEnabled(boolean enabled) {
mScrollable = enabled;
}
public boolean isScrollable() {
return mScrollable;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// if we can scroll pass the event to the superclass
if (mScrollable) return super.onTouchEvent(ev);
// only continue to handle the touch event if scrolling enabled
return mScrollable; // mScrollable is always false at this point
default:
return super.onTouchEvent(ev);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Don't do anything with intercepted touch events if
// we are not scrollable
if (!mScrollable) return false;
else return super.onInterceptTouchEvent(ev);
}
}
方法二
但此一方法,會使scrollview裡面的元件(例如textview),也不能動作(fling,swipe,click等...)
scrollView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return isBlockedScrollView;
}
});
方法三
如果scrollview裡面有textview有時會出現一些奇怪現象(畫面顯示不全,空白等)
import android.content.Context;
import android.text.Selection;
import android.text.Spannable;
import android.util.AttributeSet;
import android.widget.TextView;
public class BlockScrollView extends ScrollView {
//private boolean shouldWindowFocusWait;
public boolean isScroll =true;
public BlockScrollView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public BlockScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BlockScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void scrollTo(int x, int y) {
if (isScroll) {
super.scrollTo(x,y);
}
//do nothing
}
}
© Blogger templates Psi by Ourblogtemplates.com 2008
Back to TOP