本帖最后由 yiyaaixuexi 于 2011-12-14 21:11:18 编辑

解决方案 »

  1.   

    下面分享一下:缓冲读取txt文本的封装类:package Cool;import java.io.UnsupportedEncodingException;
    import java.util.ArrayList;
    import java.util.List;import Adapter.MyTextView;
    import Util.CT;
    import android.widget.TextView;public class TextReader {
    /** 文件的显示控件 */
    private TextView mTextView; /** 文件名 */
    private String mFilePath = null; /** 默认的文件编码形式 */
    private String mEncoding = "gb2312"; /** 文件末尾 */
    private boolean mEndOfDoc = false; /** 文件开头 */
    private boolean mBeforeOfDoc = true; /** 当前显示缓冲的显示行列表 */
    private List<TxtLine> mCurrentList = new ArrayList<TxtLine>(); /** 读取文件的输入流工具类 */
    private RandomAccessRead mRaf = null; /** 用于保存部分文件的缓冲区大小 */
    private int mDataLengthOfOneDoc = 100 * 1024; /** 屏幕宽度和高度 */
    private int mViewWidth, mViewHeight; /** 文件大小 */
    private long mFileLength; /** 缓冲区中用于显示当前页面的第一行 */
    private int mCurrentLine = 0; /** 缓冲区中用于显示当前页面的起始索引 */
    private int mCurrentOffset = 0; /** 文件中用于显示当前页面的起始索引 */
    private int mStartOffset = 0; /** 用于显示当前页面的数组的起始索引 */
    private int mDataStartLocation = 0; /** 用于显示当前页面的数组的结尾索引 */
    private int mDataEndLocation = 0; /** 当前显示的文件大小百分比 */
    private int mPercent = 0; /** 文件中用于显示当前页面的结尾索引 */
    private int mEndOffset = 0; /** 用于显示当前页面的数组 */
    private byte[] mScreenData = null; /** 用于显示的缓冲数组 */
    private byte[] mDisplayBuffer = null; /**
     * 构造函数
     * 
     * @param mTextView
     *            显示控件
     * @param mScreenWidth
     *            屏幕宽度
     * @param mScreenHeight
     *            屏幕高度
     * @param mFilePath
     *            文件路径
     * @param mEncoding
     *            文件编码
     */
    public TextReader(MyTextView mTextView, int mScreenWidth, int mScreenHeight,
    String mFilePath, String mEncoding) {
    this.mTextView = mTextView;
    this.mFilePath = mFilePath;
    this.mEncoding = mEncoding;
    this.mViewWidth = mScreenWidth;
    this.mViewHeight = mScreenHeight;
    init();
    } public void readFile() {
    readNextBuffer();
    analyzeDisplayBuffer();
    displayNextScreen(0);
    } /**
     * 获取读取文件的输入流以及文件大小
     */
    private void init() {
    // TODO Auto-generated method stub
    this.mRaf = new RandomAccessRead(mFilePath);
    this.mFileLength = mRaf.length();
    if (this.mFileLength == 0) {
    mTextView.setText(Constant.NODATAINFILE);
    return;
    }
    } /**
     * 获取下一个缓冲区
     */
    private void readNextBuffer() {
    mRaf.openNewStream();
    mRaf.locate(mStartOffset);
    byte[] b = new byte[mDataLengthOfOneDoc];
    mCurrentOffset = mStartOffset;
    int actualLength = mRaf.readBytes(b);
    if (mStartOffset == 0) {
    mBeforeOfDoc = true;
    } else {
    mBeforeOfDoc = false;
    }
    if (actualLength < mDataLengthOfOneDoc) {
    mEndOfDoc = true;
    } else {
    mEndOfDoc = false;
    } if (actualLength == -1 && mScreenData.length == 0) {// 意外到了文件流的末尾或者
    mTextView.setText("读取文件失或者文件缓冲区失败");
    return;
    } if (mEndOfDoc) {
    mDisplayBuffer = new byte[actualLength];
    System.arraycopy(b, 0, mDisplayBuffer, 0, actualLength);
    b = null;
    System.gc();
    return;
    }
    /** 最后一个换行符的索引 */
    int readDataLength = actualLength;
    int nLocation = 0;
    while (readDataLength > 0) {
    if ((b[readDataLength - 1] & 0xff) == 10) {
    nLocation = readDataLength;
    break;
    }
    readDataLength--;
    }
    if (nLocation == 0) {
    System.exit(1);
    }
    int displayLength = nLocation;
    mDisplayBuffer = new byte[displayLength];
    System.arraycopy(b, 0, mDisplayBuffer, 0, displayLength);
    b = null;
    System.gc();
    } /**
     * 获取上一个缓冲区
     */
    private void readPreBuffer() {
    int offsetOfLastScreen = mCurrentList.get(mCurrentLine).offset;
    if (offsetOfLastScreen <= mDataLengthOfOneDoc) {
    mBeforeOfDoc = true;
    // if(offsetOfLastScreen>=mFileLength){
    // mEndOfDoc=true;
    // }
    byte[] b = new byte[offsetOfLastScreen];
    mRaf.openNewStream();
    int actualLength = mRaf.readBytes(b);
    if (actualLength < offsetOfLastScreen) {
    mEndOfDoc = true;
    } else {
    mEndOfDoc = false;
    }
    if (actualLength == -1 && mScreenData.length == 0) {// 意外到了文件流的末尾或者
    mTextView.setText("读取文件失或者文件缓冲区失败");
    return;
    } if (mEndOfDoc) {
    mDisplayBuffer = new byte[actualLength];
    System.arraycopy(b, 0, mDisplayBuffer, 0, actualLength);
    b = null;
    System.gc();
    mCurrentOffset = 0;
    return;
    }
    /** 最后一个换行符的索引 */
    int readDataLength = actualLength;
    int nLocation = 0;
    while (readDataLength > 0) {
    if ((b[readDataLength - 1] & 0xff) == 10) {
    nLocation = readDataLength;
    break;
    }
    readDataLength--;
    }
    if (nLocation == 0) {
    System.exit(1);
    }
    int displayLength = nLocation;
    mDisplayBuffer = new byte[displayLength];
    System.arraycopy(b, 0, mDisplayBuffer, 0, displayLength);
    b = null;
    System.gc();
    mCurrentOffset = 0;
    return;
    } int skipLength = offsetOfLastScreen - mDataLengthOfOneDoc;
    mRaf.openNewStream();
    mRaf.locate(skipLength);
    mCurrentOffset = skipLength;
    byte[] b = new byte[mDataLengthOfOneDoc];
    int readLength = mRaf.readBytes(b);
    mBeforeOfDoc = false;
    if (readLength < mDataLengthOfOneDoc) {
    mEndOfDoc = true;
    }
    if (readLength == -1 && mScreenData.length == 0) {// 意外到了文件流的末尾或者
    mTextView.setText("读取文件失或者文件缓冲区失败");
    return;
    } int nlocation = 0;
    while (nlocation < readLength) {
    if ((b[readLength - 1] & 0xff) == 10) {
    nlocation = readLength;
    break;
    }
    readLength--;
    }
    if (nlocation == 0) {
    System.exit(1);
    } mDisplayBuffer = new byte[readLength];
    System.arraycopy(b, 0, mDisplayBuffer, 0, readLength);
    b = null;
    System.gc();
    }
      

  2.   

    /**
     * 对缓冲区进行字符解析
     */
    private void analyzeDisplayBuffer() {
    if (mDisplayBuffer == null) {
    return;
    }
    mCurrentList.clear();
    TxtLine line = new TxtLine(mCurrentOffset, 0, 0);
    mCurrentList.add(line);
    int length = 0;
    int offset = 0;
    int width = 0;
    int beforeLength = 0;
    for (offset = 0; offset < mDisplayBuffer.length;) {
    int b = mDisplayBuffer[offset] & 0xff;
    if (b == 13) {// '\r'
    mDisplayBuffer[offset] = ' ';
    } if (b == 10) {// '\n'
    length++;
    offset++;
    beforeLength++;
    mCurrentList.add(new TxtLine(mCurrentOffset + offset, length,
    beforeLength));
    length = 0;
    width = 0;
    continue;
    } if (b > 0x7f) {// chinese
    if (width + CT.ChineseFontWidth > mViewWidth) {
    mCurrentList.add(new TxtLine(mCurrentOffset + offset,
    length, beforeLength));
    length = 0;
    width = 0;
    continue;
    } else {
    offset += 2;
    length += 2;
    beforeLength += 2;
    width += CT.ChineseFontWidth;
    }
    } else {// Ascii
    int aw = CT.upperAsciiWidth;
    if (b >= 65 && b <= 90) {
    aw = CT.lowerAsciiWidth;
    }
    if (width + aw > mViewWidth) {
    mCurrentList.add(new TxtLine(mCurrentOffset + offset,
    length, beforeLength));
    length = 0;
    width = 0;
    continue;
    } else {
    offset += 1;
    length += 1;
    beforeLength += 1;
    width += aw;
    }
    }
    }
    mCurrentList.add(new TxtLine(mCurrentOffset + offset, length,
    beforeLength));
    mCurrentLine = 0;
    System.gc();
    } /**
     * 显示下一页
     * 
     * @param n
     *            显示的行数
     */
    public void displayNextScreen(int n) {
    int tempLine = mCurrentLine;
    int lastLine = tempLine + n;
    int lastIndex = mCurrentList.size() - 1;
    if (lastLine + CT.mLinesOfOneScreen > lastIndex) {// 超过缓冲区
    if (mEndOfDoc) {// 文件末尾
    if (lastIndex <= CT.mLinesOfOneScreen) {// 如果文件大小不足以或者刚好显示整个页面
    mStartOffset = mCurrentList.get(0).offset;
    mDataStartLocation = mCurrentList.get(0).beforeLineLength;
    mEndOffset = mCurrentList.get(lastIndex).offset;
    mDataEndLocation = mCurrentList.get(lastIndex).beforeLineLength;
    setData(mDataStartLocation, mDataEndLocation);
    } else {
    mStartOffset = mCurrentList.get(lastLine).offset;
    mDataStartLocation = mCurrentList.get(lastLine).beforeLineLength;
    mEndOffset = mCurrentList.get(lastIndex).offset;
    mDataEndLocation = mCurrentList.get(lastIndex).beforeLineLength;
    setData(mDataStartLocation, mDataEndLocation);
    }
    } else {
    readNextBuffer();
    analyzeDisplayBuffer();
    mCurrentLine = n;//重新定位到末行
    lastIndex = mCurrentList.size() - 1;
    mStartOffset = mCurrentList.get(mCurrentLine ).offset;
    mDataStartLocation = mCurrentList.get(mCurrentLine).beforeLineLength;
    // lastLine = mCurrentLine + n;
    // lastIndex = mCurrentList.size() - 1;
    if (lastIndex <= CT.mLinesOfOneScreen) {
    mStartOffset = mCurrentList.get(0).offset;
    mDataStartLocation = mCurrentList.get(0).beforeLineLength;
    mEndOffset = mCurrentList.get(lastIndex).offset;
    mDataEndLocation = mCurrentList.get(lastIndex).beforeLineLength;
    setData(mDataStartLocation, mDataEndLocation);
    } else {
    int i=mCurrentLine+CT.mLinesOfOneScreen;
    if(i>=mCurrentList.size()){
    i=mCurrentList.size()-1;
    }
    mEndOffset = mCurrentList.get(i).offset;
    mDataEndLocation = mCurrentList.get(i).beforeLineLength;
    setData(mDataStartLocation, mDataEndLocation);
    }
    }
    return ;
    } else {
    mCurrentLine = lastLine;
    mStartOffset = mCurrentList.get(mCurrentLine).offset;
    mDataStartLocation = mCurrentList.get(mCurrentLine).beforeLineLength;
    mEndOffset = mCurrentList.get(mCurrentLine + CT.mLinesOfOneScreen).offset;
    mDataEndLocation = mCurrentList.get(mCurrentLine
    + CT.mLinesOfOneScreen).beforeLineLength;
    setData(mDataStartLocation, mDataEndLocation);
    return;
    }
    } /**
     * 显示上一页
     * 
     * @param n
     *            显示的行数
     */
    public void displayPreScreen(int n) {
    int tempLine = mCurrentLine;
    int lastLine = tempLine - n;
    if (lastLine <= 0) {
    lastLine = 0;
    }
    if (lastLine == 0 && !mBeforeOfDoc) {
    readPreBuffer();
    analyzeDisplayBuffer();
    int lastIndex = mCurrentList.size() - 1;
    if (lastIndex <= CT.mLinesOfOneScreen) {
    mStartOffset = mCurrentList.get(0).offset;
    mDataStartLocation = mCurrentList.get(0).beforeLineLength;
    mEndOffset = mCurrentList.get(lastIndex).offset;
    mDataEndLocation = mCurrentList.get(lastIndex).beforeLineLength;
    setData(mDataStartLocation, mDataEndLocation);
    } else {
    mCurrentLine = lastIndex - CT.mLinesOfOneScreen;
    if (mCurrentLine < 0) {
    mCurrentLine = 0;
    }
    mStartOffset = mCurrentList.get(mCurrentLine).offset;
    mDataStartLocation = mCurrentList.get(mCurrentLine).beforeLineLength;
    mEndOffset = mCurrentList.get(lastIndex).offset;
    mDataEndLocation = mCurrentList.get(lastIndex).beforeLineLength;
    setData(mDataStartLocation, mDataEndLocation);
    }
    return;
    }
    if (lastLine == 0 && mBeforeOfDoc) {
    mCurrentLine = 0;
    mStartOffset = 0;
    mDataStartLocation = 0;
    int lastIndex = mCurrentList.size() - 1;
    if (lastIndex <= CT.mLinesOfOneScreen) {
    mEndOffset = mCurrentList.get(lastIndex).offset;
    mDataEndLocation = mCurrentList.get(lastIndex).beforeLineLength;
    } else {
    mEndOffset = mCurrentList.get(CT.mLinesOfOneScreen).offset;
    mDataEndLocation = mCurrentList.get(CT.mLinesOfOneScreen).beforeLineLength;
    }
    setData(mDataStartLocation, mDataEndLocation);
    return;
    } if (lastLine > 0) {
    int futureLine = lastLine + CT.mLinesOfOneScreen;
    if (lastLine > mCurrentList.size() - 1) {
    lastLine = mCurrentList.size() - 1;
    }
    mCurrentLine = lastLine;
    mStartOffset = mCurrentList.get(mCurrentLine).offset;
    mDataStartLocation = mCurrentList.get(mCurrentLine).beforeLineLength;
    mEndOffset = mCurrentList.get(futureLine).offset;
    mDataEndLocation = mCurrentList.get(futureLine).beforeLineLength;
    setData(mDataStartLocation, mDataEndLocation);
    return;
    }
    } public void displayScreenbyLine(int lineNumber) {
    if (lineNumber > 0) {
    this.displayNextScreen(lineNumber);
    } else {
    this.displayPreScreen(Math.abs(lineNumber));
    } } /**
     * 设置数据
     * 
     * @param start
     *            起始索引
     * @param end
     *            终点索引
     */
    public void setData(int start, int end) {
    mScreenData = new byte[end - start];
    mCurrentOffset = mStartOffset;
    mPercent = (int) (((double) mCurrentOffset / (double) mFileLength) * 100);
    System.arraycopy(mDisplayBuffer, start, mScreenData, 0,
    mScreenData.length);
    try {
    mTextView.setText(new String(mScreenData, mEncoding));
    } catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    } /**
     * 从指定的索引读取缓冲区
     * 
     * @param offset
     *            起始索引
     */
    public void readBufferByOffset(int offset) {
    mStartOffset = offset;
    mCurrentList.clear();
    mCurrentLine = 0;
    readNextBuffer();
    analyzeDisplayBuffer();
    displayNextScreen(0);
    } /**
     * 获取文件的当前索引
     * 
     * @return
     */
    public int getCurrentLineOffset() {
    return mStartOffset;
    } /**
     * 获取当前行的指定字节组成的字符串
     * 
     * @return
     */
    public String getCurrentLineString() {//
    int length = mScreenData.length;
    String s = Constant.BOOKMARK;
    if (length < 10) {
    try {
    s = new String(mScreenData, this.mEncoding);
    } catch (UnsupportedEncodingException e) {
    return s;
    }
    } else {
    int lineFlag = 0;
    for (int i = 0; i < 10; i++) {
    int temp = mScreenData[i] & 0xff;
    if (temp == 13 || temp == 10) {
    lineFlag = i;
    }
    }
    byte[] b = null;
    if (lineFlag != 0) {//如果前10个字节包含换行符,那么从换行符之前取字段
    b = new byte[lineFlag];
    } else {
    int temp = mScreenData[9] & 0xff;
    if (temp > 0x7f) {// 如果是中文字节,那么可能是半个中文字,那么这里应该再往后取两个字节
    b = new byte[12];
    } else {//如果只是英文字母,那么直接在这个地方开始取字段
    b = new byte[10];
    }
    }
    System.arraycopy(mScreenData, 0, b, 0, b.length);
    try {
    s = new String(b, this.mEncoding);
    } catch (UnsupportedEncodingException e) {
    return s;
    }
    }
    System.gc();
    return s;
    } public void close() {
    mRaf.close();
    } /** Percent */
    public int getPercent() {
    return mPercent;
    }
    }
      

  3.   

    以上就是就是缓冲读取的封装类,是在CoolReader的最原始版本上进行功能修改,代码都有注释,本意是抛砖引玉,希望有兴趣的同学一起研究
    下面就是调用类了://跳页,因为有乱码问题,取巧获取最近的一个换行符,避免乱码
    private void jumpPage() {
    // TODO Auto-generated method stub
    mPercent = (int) (((double) current_startIndex / (double) CT.mFileLength) * 100);
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(R.string.jump_page_title);
    View view = LayoutInflater.from(this).inflate(
    R.layout.reader_menu_jump_page, null);
    final SeekBar bar = (SeekBar) view
    .findViewById(R.id.jump_page_seek_bar);
    bar.setProgress(mPercent);
    final TextView text = (TextView) view
    .findViewById(R.id.jump_page_show_percent);
    text.setText(mPercent + "%");
    bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
    // TODO Auto-generated method stub } @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    // TODO Auto-generated method stub } @Override
    public void onProgressChanged(SeekBar seekBar, int progress,
    boolean fromUser) {
    // TODO Auto-generated method stub
    mPercent = progress;
    text.setText(progress + "%");
    RandomAccessRead ran = new RandomAccessRead(_mFilePath);
    current_startIndex = (int) ((progress * 0.01) * CT.mFileLength);
    ran.locate(current_startIndex);
    int temp;
    do {// 获取从current_startIndex开始的第一个换行符,这样就避免读取半个汉字字节
    temp = ran.read();
    current_startIndex += 1;
    if ((temp & 0xff) == 10) {
    break;
    }
    } while (true);
    ran.close();
    mTextReader.readBufferByOffset(current_startIndex);
    }
    });
    builder.setView(view);
    builder.setNegativeButton(R.string.widget_cancel,
    new OnClickListener() { @Override
    public void onClick(DialogInterface dialog, int which) {
    // TODO Auto-generated method stub
    dialog.dismiss();
    }
    });
    Dialog dialog = builder.create();
    dialog.show();
    }/**
     * 载入书籍的数据
     */
    private void loadData() {
    mReaderBytes = new RandomAccessRead(_mFilePath);
    CT.mFileLength = mReaderBytes.length();
    byte[] encodings = new byte[400];
    mReaderBytes.readBytes(encodings);
    mReaderBytes.close();
    /** 以下是检测文件的编码 */
    BytesEncodingDetect be = new BytesEncodingDetect();
    this.mEncoding = BytesEncodingDetect.nicename[be
    .detectEncoding(encodings)];
    /** 检测文件的编码结束 */
    /** load the attribute for font */
    Paint tp = mTextView.getPaint();
    /** Ascii char width */
    CT.upperAsciiWidth = (int) tp.measureText(Constant.UPPERASCII);
    CT.lowerAsciiWidth = (int) tp.measureText(Constant.LOWERASCII);
    /** Chinese char width */
    CT.ChineseFontWidth = (int) tp.measureText(
    Constant.CHINESE.toCharArray(), 0, 1); mTextReader = new TextReader(mTextView, CT.mScreenWidth,
    CT.mScreenHeight, _mFilePath, mEncoding);
    if (current_startIndex == 0) {
    mTextReader.readFile();
    } else {
    mTextReader.readBufferByOffset(current_startIndex);
    }
    showToast();
    }
    //初始化界面
    private void init() {
    // TODO Auto-generated method stub
    mTextView.setBackgroundResource(BookConfig.backgroundResource);
    CT.mScreenHeight = this.getWindowManager().getDefaultDisplay()
    .getHeight();
    CT.mScreenWidth = this.getWindowManager().getDefaultDisplay()
    .getWidth();
    mTextView.setTextSize(BookConfig.fontSize);
    mTextView.setTextColor(BookConfig.fontColor);
    mTextView.setLineSpacing(0, 1.2f);
    }
    //下一页
    private void pageDown() {
    // TODO Auto-generated method stub
    if (mScroll.getScrollY() != 0) {// 如果滑块不是停在最前面,则自动滚到最前端
    mScroll.smoothScrollTo(0, 0);
    }
    mTextReader.displayScreenbyLine(CT.mLinesOfOneScreen);
    }
    //上一页
    private void pageUp() {
    if (mScroll.getScrollY() != 0) {// 如果滑块不是停在最前面,则自动滚到最前端
    mScroll.smoothScrollTo(0, 0);
    }
    mTextReader.displayScreenbyLine(-CT.mLinesOfOneScreen);
    }@Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
    float velocityY) {
    // TODO Auto-generated method stub
    if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE// 手势翻页上一页
    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
    pageDown();
    return true;
    } else if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE// 手势翻页下一页
    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
    pageUp();
    return true;
    } else {
    return false;
    }
    }
      

  4.   

    主要是针对如何避免乱码想跟大家讨论一下,如果研究过iReader同学会发现这个软件跳页的时候根本不会出现乱码问题也不会出现跳页后翻页,文字不连续的问题,希望借这个机会,向大家问这个问题
      

  5.   

    楼主的代码可以来个合集了。
    android做了八个月了,mediaplayer的播放框架stagefright有了些了解。
      

  6.   

    好贴,一下,希望下年毕业的时候能找到android的工作!兴趣所在!
      

  7.   

    我对Android系统框架 和 Camera 有一点了解。
      

  8.   


    如果想明白系统工作原理,不得不学习Linux了~~  先看看 Android framework,再看linux kernel
      

  9.   

    改了一年的bug,对sms,contacts,browser,对媒体了解了一些。
      

  10.   

    学习framework层一年半了,主要内容有:
    1.曾经在android1.6上实现所有phone相关的功能,用的LC6311模块,包括自己扩展可视通话功能
    2.StageFright,几乎全格式支持,利用自家芯片硬解码
    3.GPU 2D/3D 加速移植
    4.把V8等移植在amrV5 CPU上运行等armV5 兼容性改进
    5.其它电源管理,wifi,bt,touch,vold,recovery升级包等乱七八糟的需求及bug修改
    移植过android1.6/2.0/2.1/2.3/4.0
    自学过surface机制,binder工作原理,之前一直搞wince移植比较多,window开发经验较多,
    做android时,才开始学习linux,感觉linux还是很伟大的对android学习的最大感受:设计这款系统的人很牛X,但系统结构太臃肿,比较耗CPU及内存
      

  11.   

    兄弟你很强啊,想请教你两方面的事情:
    1.扩展可视通话功能,是如何实现的,你说的LC6311模块又是怎么回事啊,见笑了,我对framework只停留在好奇层次
    2.你说你移植过android1.6/2.0/2.1/2.3/4.0,是怎么回事啊 ,有相关的学习资料吗?
    先谢过了啊
      

  12.   

    LC6311 是TD-SCDMA无线模块,用来通信的,可视通话就是对phone模块进行功能扩展
    android1.6不支持可视通话,主要有camera数据压缩发送,vp数据解压显示等操作android1.6/2.0/2.1/2.3/4.0移植,因为我们是做芯片的,每出来一款android版本
    我们都要让它先在我们平台上运行,2.0/2.1相差不大,是给别人平台做的,学习资料
    现在网上已经很多了,一年前很少,主要学习方法是看代码了
      

  13.   

    1. 分辨率太多,处理比较麻烦
    2. 内存需要优化,尤其是图片较多的时候,容易内存溢出
    3. 一个应用程序如果太臃肿,感觉需要使用多进程来处理,,把数据处理放到另外一个进程当中去Service。
      

  14.   

    http://blog.csdn.net/sunshine0990/article/details/7068956
     请求各位android大侠给些建议。
      

  15.   

    http://blog.csdn.net/sunshine0990/article/details/7068956
    请求各位android大侠给些建议。
      

  16.   

    之前听妞妞说在研究mplayer,想来是对多媒体方面颇多研究,没说错吧?希望可以多交流
      

  17.   

    唉,javase还不熟,android还遥远呢
      

  18.   

    刚转做android系统开发,感觉很多架构的知识,有点难度!
      

  19.   

    呵呵,我准备用Android完成一个移动客户端的毕业设计,期待中
      

  20.   

    不管怎么样,顶下楼主,帮过我好几次忙了,Thank you very much
      

  21.   

    暑假做了一个项目,刚了解android,对很多都不熟悉,所以痛苦啊
      

  22.   


    System.out.printn("酱油....");
      

  23.   

    正在加紧学习中,公司明年要开始做android应用开发了。
      

  24.   

    正在加紧学习中,公司明年要开始做android应用开发了。
      

  25.   

    新手上路,没什么心得。还想请教一下大家,现在企业招的Android开发人员最基本要懂Android的那些内容?
      

  26.   

    我现在只是一名学生;才刚刚学java的最低层的代码,很多都不会 ,我应该咋办呢?安卓我很喜欢可是就是不会。
      

  27.   

    我现在只是一名学生;才刚刚学java的最低层的代码,很多都不会 ,我应该咋办呢?安卓我很喜欢可是就是不会。
      

  28.   

    惭愧,一出校门 就在做 android连学加做 也有 8个月了 
    可,还是 停留在应用层 framework想研究 只能看懂 别人 剖析的  很小一部分(binder,
    ams)至今还在做 app应用 ,顺便问一下 mediaplayer的 流怎么获取 如何 在缓冲完了后 取出 完整的 流 并
    保存成 文件。
      

  29.   

    最近我也开始学android了,呵呵。
      

  30.   

    正在安卓上做flex开发,没有一点头绪,都不知道各位说的是啥.......
    悲催
      

  31.   

    进来谈下自己的android开发心得
      

  32.   

    Android平台,类库丰富、功能强大,开发效率高。
    App开发门槛降低,吸引用户的不再是技术,而是服务和特色。