編輯:高級開發
問了google也沒有好解答,在android的google code裡issue 1590就是在陳述這個問題,下面Comment提供的方法我試不出來,有趣的是用adb logcat在console下是不會有亂碼的,所以問題一定出在ADT上,最近自已build了ADT trunk來用,剛好又遇到需要dump中文的data來debug的case,所以就嘗試著自已來trace問題。
LogCat的相關的code都在LogPanel.Java裡,
Java代碼
public class LogPanel extends SelectionDependentPanel {
private LogCatOuputReceiver mCurrentLogCat;
@Override
protected Control createControl(Composite parent) {...}
private TabItem createTab(LogFilter filter, int index, boolean fillTable) {...}
/**
* Sent when a new device is selected. The new device can be Accessed
* with {@link #getCurrentDevice()}.
*/
@Override
public void deviceSelected() {
startLogCat(getCurrentDevice());
}
public void startLogCat(final IDevice device) {
if (device == mCurrentLoggedDevice) {
return;
}
// if we have a logcat already running
if (mCurrentLoggedDevice != null) {
stopLogCat(false);
mCurrentLoggedDevice = null;
}
resetUI(false);
if (device != null) {
// create a new output receiver
mCurrentLogCat = new LogCatOuputReceiver();
// start the logcat in a different thread
new Thread("Logcat") { //$NON-NLS-1$
@Override
public void run() {
while (device.isOnline() == false &&
mCurrentLogCat != null &&
mCurrentLogCat.isCancelled == false) {
try {
sleep(2000);
點擊下載:重新編譯後的的ADT
接上頁
} catch (InterruptedException e) {
return;
}
}
if (mCurrentLogCat == null || mCurrentLogCat.isCancelled) {
// logcat was stopped/cancelled before the device became ready.
return;
}
try {
mCurrentLoggedDevice = device;
device.executeShellCommand("logcat -v long", mCurrentLogCat, 0 /*timeout*/); //$NON-NLS-1$
} catch (Exception e) {
Log.e("Logcat", e);
} finally {
// at this point the command is terminated.
mCurrentLogCat = null;
mCurrentLoggedDevice = null;
}
}
}.start();
}
}
}
public class LogPanel extends SelectionDependentPanel {
private LogCatOuputReceiver mCurrentLogCat;
@Override
protected Control createControl(Composite parent) {...}
private TabItem createTab(LogFilter filter, int index, boolean fillTable) {...}
/**
* Sent when a new device is selected. The new device can be Accessed
* with {@link #getCurrentDevice()}.
*/
@Override
public void deviceSelected() {
startLogCat(getCurrentDevice());
}
public void startLogCat(final IDevice device) {
if (device == mCurrentLoggedDevice) {
return;
}
// if we have a logcat already running
if (mCurrentLoggedDevice != null) {
stopLogCat(false);
mCurrentLoggedDevice = null;
}
resetUI(false);
if (device != null) {
// create a new output receiver
mCurrentLogCat = new LogCatOuputReceiver();
// start the logcat in a different thread
new Thread("Logcat") { //$NON-NLS-1$
@Override
public void run() {
點擊下載:重新編譯後的的ADT
接上頁
while (device.isOnline() == false &&
mCurrentLogCat != null &&
mCurrentLogCat.isCancelled == false) {
try {
sleep(2000);
} catch (InterruptedException e) {
return;
}
}
if (mCurrentLogCat == null || mCurrentLogCat.isCancelled) {
// logcat was stopped/cancelled before the device became ready.
return;
}
try {
mCurrentLoggedDevice = device;
device.executeShellCommand("logcat -v long", mCurrentLogCat, 0 /*timeout*/); //$NON-NLS-1$
} catch (Exception e) {
Log.e("Logcat", e);
} finally {
// at this point the command is terminated.
mCurrentLogCat = null;
mCurrentLoggedDevice = null;
}
}
}.start();
}
}
}
class Device的method executeShellCommand有三個參數分別是String command, IShellOutputReceiver receiver, int maxTimeToOutputResponse,它會透過class AdbHelper來做一下adb utility的指令操作。在第xx行時,執行了logcat -v long並把輸出丟給LogCatOutputReceiver處理,所以我們的重點在於class LogCatOutputReceiver。繼續追進去method executeShellCommand會發現它會把所有接收的data丟給interface IShellOutputReceiver的method addOutput處理,現在這個角色就是class LogCatOutputReceiver,而它的method addOutput是繼承class MultiLineReceiver而來,問題就出在這裡,把ISO -8859-1改成UTF-8就可以了...
Java代碼
public abstract class MultiLineReceiver implements IShellOutputReceiver {
/* (non-Javadoc)
* @see com.android.ddmlib.adb.IShellOutputReceiver#addOutput(
* byte[], int, int)
*/
public final void addOutput(byte[] data, int offset, int length) {
if (isCancelled() == false) {
String s = null;
try {
s = new String(data, offset, length, "ISO-8859-1");
點擊下載:重新編譯後的的ADT
接上頁
//問題在這裡,把所有輸出的字串都使用ISO-8859-1 decode} catch (UnsupportedEncodingException e) {
// normal encoding didn't work, try the default one
s = new String(data, offset,length);
}
// ok we've got a string
if (s != null) {
// if we had an unfinished line we add it.
if (mUnfinishedLine != null) {
s = mUnfinishedLine + s;
mUnfinishedLine = null;
}
// now we split the lines
mArray.clear();
int start = 0;
do {
int index = s.indexOf("", start); //$NON-NLS-1$
// if was not found, this is an unfinished line
// and we store it to be processed for the next packet
if (index == -1) {
mUnfinishedLine = s.substring(start);
break;
}
// so we found a ;
// extract the line
String line = s.substring(start, index);
if (mTrimLines) {
line = line.trim();
}
mArray.add(line);
// move start to after the we found
start = index + 2;
} while (true);
if (mArray.size() > 0) {
// at this point we've split all the lines.
// make the array
String[] lines = mArray.toArray(new String[mArray.size()]);
// send it for final processing
processNewLines(lines);
}
}
}
}
}
public abstract class MultiLineReceiver implements IShellOutputReceiver {
/* (non-Javadoc)
* @see com.android.ddmlib.adb.IShellOutputReceiver#addOutput(
* byte[], int, int)
*/
public final void addOutput(byte[] data, int offset, int length) {
if (isCancelled() == false) {
String s = null;
try {
s = new String(data, offset, length, "ISO-8859-1");
點擊下載:重新編譯後的的ADT
接上頁
//問題在這裡,把所有輸出的字串都使用ISO-8859-1 decode} catch (UnsupportedEncodingException e) {
// normal encoding didn't work, try the default one
s = new String(data, offset,length);
}
// ok we've got a string
if (s != null) {
// if we had an unfinished line we add it.
if (mUnfinishedLine != null) {
s = mUnfinishedLine + s;
mUnfinishedLine = null;
}
// now we split the lines
mArray.clear();
int start = 0;
do {
int index = s.indexOf("", start); //$NON-NLS-1$
// if was not found, this is an unfinished line
// and we store it to be processed for the next packet
if (index == -1) {
mUnfinishedLine = s.substring(start);
break;
}
// so we found a ;
// extract the line
String line = s.substring(start, index);
if (mTrimLines) {
line = line.trim();
}
mArray.add(line);
// move start to after the we found
start = index + 2;
} while (true);
if (mArray.size() > 0) {
// at this point we've split all the lines.
// make the array
String[] lines = mArray.toArray(new String[mArray.size()]);
// send it for final processing
processNewLines(lines);
}
}
}
}
}
然後重新編譯DDMS即可。
$javac -classpath ./ddms.jar:./ddmlib.jar MultiLineReceiver.Java
下面便為重新編譯後的的ADT,其中除了中文問題,其他與官方的完全相同。
點擊下載:重新編譯後的的ADT
SDK and AVD Manager 對話框內的New 按鈕.為你的AVD鍵入如下的設置:1234Name: android_1.6Target: Google AP
android應用程序是由Java語言開發的也只能用Java語言開發,Google對android采用了一種全面霸權式的管理,完全不是其他開源軟件的開發方式,一切都由G
我們已經為喜歡Android 3.0的朋友提供android 3.0 SDK下載,本文我們將向大家介紹android 3.0 SDK安裝教程,本教程與android 2
android系統默認的啟動之後的icon布局是4行4列,第一行由search widget完全占據。這樣的設計對於小屏幕的手機比較合適,但是對於大屏幕的tablet