android笔记

【2010/2/27】

1:
android里view显示的位置都是针对layout来说的,不是针对手机屏幕左上角。

2:
view里显示图片是,要对图片进行 处理,将普通图片转变为位图,语法是:
Bitmap bitmap = Bitmap.createBitmap(width, height,
    Bitmap.Config.ARGB_8888);
  //像管道一样
  Canvas canvas = new Canvas(bitmap);
  drawable.setBounds(0, 0, width, height);
  drawable.draw(canvas);

3:
围棋主页面中,要想让滚动条左右滑动,就要反复的调用rootMainView 里的onDraw()方法,并且每次调用都要改变
横坐标的值;但是这个调用onDraw方法的任务必须通过RootMainAct(或RootAct)的handler放到主线程的message queue
里,让线程来执行,如果另开一个线程,如在timer.schedule()这个线程里调用rootMainView里的invalidate方法(这个方法
会调用onDraw方法),希望通过这个方式来实现滚动条左右滑动,是不能实现的(结果是滚动条停留在一个位置,原因可能是
主线程已经退出)。

围棋主页面中,要想让文字变化,不能在rootMainAct的onCreate方法里,用Thread技术来实现,因为这样的话,手机屏幕上显示
的是最后的一串文字(这个是因为在屏幕加载前,会先确定textView的值,这里虽然将textview的值改了四次,但只会显示最后一次
的文字值。);

如果开启一个线程,在这个线程里希望改textview的值,则运行程序会报错。

所以只有另开启一个线程,在这个线程里让这个线程通过handler把要改变文字值的这个动作传给主线程,这样就可以了。


【2010/2/27】

1:

package com.gaoge.android.feature;


import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.util.Log;

 

public class Activity1 extends Activity
{
    /** Called when the activity is first created. */
   
@Override
    public void onCreate(Bundle savedInstanceState)
{
        super.onCreate(savedInstanceState);
      
 Intent intent = new Intent(this, Activity2.class);
       
 
      setContentView(R.layout.main);
      
 Log.i("msg", "this is activity1");

this.startActivityForResult(intent, 1001);
   
}

 
@Override
 
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
  // TODO Auto-generated method stub
  
super.onActivityResult(requestCode, resultCode, data);
  
Log.i("-------requestCode", "requestCode is: " + requestCode);
 
}

}      

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class Activity2 extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity2);
  Log.i("------------activity2", "this is output by activity2");
//  
 }

}
报错:
activityNotFoundException
结果发现在androidManifest.xml里没有配置activity2
<activity android:name=".Activity2">
</activity>
然后成功,虽然主页面配置的是activity1,然而因为在activity1中调用了activity2,所以第一个显示的是activity2.
上两个是文件的源代码:
如果在文件Activity2里没有this.finish()方法的调用,则log.cat中输出了
Log.i("msg", "this is activity1");
 
Log.i("------------activity2", "this is output by activity2");
但是没有输出
Log.i("-------requestCode", "requestCode is: " + requestCode);

 

【2010/3/1】

1:
动画只能针对一个view,而android中又把absulteLayout给废弃了,所以要想一下子显示几个view的动画效果,就可以把这几个view都放在一个absulteLayout,在把
这个absulteLayout放到一个relativeLayout中。(因为如果直接把这几个view放到一个relativeLayout中的话,relativeLayout对控件的定位只能是相对其他控件的,
没有absulteLayout给控件直接定位坐标方便)

2:
android中,使用继承的时候,有些变量时父类有的,子类继承自父类也可以得到在自己子类实例中得到父类的属性,如果继承的层次比较深的话,某些话该放在子类还是
父类中就比较容易出错了,如relativeLayout = (RelativeLayout)this.findViewById(R.id.RelativeLayout01);这句话放在Main4Act的onCreate()里就出错,放在
Base4Act中的onCreate()话就好使,因为在Base4Act中用到了relativeLayout 。

【2010/3/3】

1.
父类中的protected方法子类是可以访问的,父类中的private方法子类是不能访问的;但是假如父类的protect方法调用父类的private方法,子类再调用父类的protected
方法,则就可以间接达到子类调用父类private方法的目的。

【2010/3/10】

1:
父类中有static属性(如int i)的时候,说明这时候不管是父类的类名访问该属性,还是父类的对象访问该属性,得到的结果都一样。所以当子类继承自父类以后,
实例化一个子类的对象出来的同时也要相应的首先实例化一个父类的对象出来,这时候所有的子类对象访问父类对象的i属性,得到的i的值都是一样的。而且一旦有一个子类的
对象修改了改属性i的值,那么其他子类对象的父类对象的i属性也会跟着发生更改。所以结论是这个static属性虽然可以被任何一个子类修改,但是所有子类的这个属性i的值
是一样的。

而如果父类的static属性是 final的话,因为final属性不能被修改,所以所有子类能访问到得改属性的值都是固定的,一样的。
 【2010-3-18】
1:
android客户端和服务器连接上以后,如果是强行关掉服务器(点红色按钮)则服务器端没反应,
android客户端会报错,报的错是
java.net.SocketException:The connection was reset.
java.net.SocketException:The connection was reset.(两条错误)
报错的代码是:is.read(readBytes);

2:
android客户端和服务器连接上以后,如果是关掉客户端的wifi网络,则服务器端没有立马报错,而
客户端报的错事:
java.net.SocketException:The operation timed out.
java.net.SocketException:The operation timed out.(两条错误)
报错的代码是:is.read(readBytes);

3:
android客户端和服务器连接上以后,如果客户端定时(每隔3秒)向服务器发送数据,如果这时候关
掉wifi网络,则报的是
java.net.SocketException:Broke pipe
报错代码是:os.write(msg.getBytes());
如果再打开wifi,我在receiver里再次调用了客户端的connectToServer的方法,所以就会再次调用
socket = new Socket("192.168.10.2",8869);
is = socket.getInputStream();
os = socket.getOutputStream();
就会自动的再次向服务器端发送消息(但是之前创建的socket,is和os都没有还没有处理),所以要
在catch代码块里关闭掉之前创建的socket,is和os,节省内存。

4:
android客户端和服务器连接上以后,如果客户端定时(每隔3秒)向服务器发送数据,强行关掉服务器(点红色按钮)则服务器端没反应,
android客户端会报错,报的错是
java.net.SocketException:Broke pipe
报错代码是:os.write(msg.getBytes());
如果再启动服务器端,则客户端仍旧不能正常发送消息,因为之前创建的socket已经断掉了,所以要在
客户端添加自动连接服务器的方法,在catch代码块里调用这个方法,重新创建一个sokcet和服务器连接。

5:

android客户端和服务器连接上以后,如果客户端定时(每隔3秒)向服务器发送数据,强行关掉服务器(点红色按钮)则服务器端没反应,
android客户端会报错,报的错是:
java.net.ConnectException:Connection refused
报错的代码是:
socket = new Socket("192.168.10.2",8869);
这个和4的不同是这次添加了客户端自动连接服务器的代码,当服务器强行关闭的时候,就把socket,os,is全部设置为空,所以不会再执行
4中的os.write(msg.getBytes());代码了,也就不会报java.net.SocketException:Broke pipe这个异常了;因为客户端要自动重新连接服务器
所以就会调用socket = new Socket("192.168.10.2",8869);这行代码,所以(只要服务器没有重新启动)就报Connection refused这个错,当
重新服务器以后Connection refused这个错就消失了。

【2010-3-19】
1:
在catch代码块里,Log.e()打印不出来信息

2:
BroadcastReceiver 在用这个的时候,有时候会报leaked IntentReceiver这个错误。

3:
DeskAdapter中如何显示100个桌子信息,是根据
 @Override
 public int getCount() {
  return things.size();
 }
来显示,而things是
private List<String> things = new ArrayList<String>();
things中有多少条记录,就显示及行桌子,也和
 @Override
 public View getView(int position, View convertView, ViewGroup parent)
 {
  convertView = flater.inflate(R.layout.deskitem, null);
  return convertView;
 }
有关,不过getView方法中只是指定了ListView的每一个元素的外观是什么样的,并没有指出显示条目的数量。

4:
ListView控件默认是黑色边框,可以通过属性android:cacheColorHint="#E4E4E4"来修改

 

2010-3-22】
1:
继承和多态真是太可怕了,继承多态用的好的话,能让子类的代码量从几百行降低到几十行,甚至是十几行,太不可思议了!

2:
在分析一个子类的程序的时候,如果发现子类中调用了一个方法A,而该方法没有在子类中定义,那么就需要看看A这个方法在最近的父类中的定义;
在父类中A这个方法很可能还调用了B这个方法,而B这个方法你可能在子类中见都没有见过,因为如果子类中对B方法的实现不坐特殊要求的话,
就可以默认调用父类对B方法的实现。如果子类中有B方法的话,那么父类中A方法调用的B方法,就是调用子类中实现的B这个方法。

3:
继承中,父类相当于一个流程图,定义了方法调用之间的关系,如A调用B,C,D;B又调用E,F;C又调用G,H等;而子类可以重新覆盖这些父类的方法
那么当父类按照流程图调用的时候,如果子类没有覆盖,就调用自己的这些函数,如果子类覆盖了这些方法之中的某些方法,如B,E,F,那么父类这时候
调用的就是子类的B,E,F方法,当然不同的子类再覆盖父类的B,E,F方法的时候可以提供不同的实现;当然也可以在父类的方法中用instanceof关键字来
判断this的类,并根据不同的类执行不同的操作。


【2010-3-30】
1:
今天想实现这样一个效果,就是在下完围棋,双方请求计算结果,在计算结果的时候,手机显示进度条对话框,等计算完结果以后,在关闭进度条对话框,接着
弹出一个计算 结果对话框,显示最后的计算结果。

刚开始这样写:
(一):
    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch(item.getItemId())
        {
        case CALCULATE:
            startProgressDialog();
           
            result = board.judgeWhoWinBy75();
            endProgressDialog();
            new CalculateDlg(BoardAct.this, result).show();
                   
           
           
           
            break;
        }
        return super.onOptionsItemSelected(item);
    }

这种写法的结果 就是:主要有两种:
1:点完按钮以后,屏幕不动,像死机了一样,没有出现进度条对话框,过了一段时间,大概有4,5秒(可能是在计算围棋胜负)后
,弹出一个计算结果对话框,计算结果正确。
2:点完按钮以后,屏幕不动,像死机了一样,没有出现进度条对话框,过了一段时间,大概有4,5秒(可能是在计算围棋胜负)
后出现一个android系统对话框,提示该程序无反映(这种出现系统对话框的前提我猜测可能就是主线程在计算围棋胜负的时候),
用的时间太长了,系统可能觉得其已经死机了)是强行关闭还是等待,晕,真和死机差不多了



(二):

那就换种写法,再开启一个线程:
    switch(item.getItemId())
        {
        case CALCULATE:
           
            new Thread(new Runnable() {
               
                @Override
                public void run() {
                    startProgressDialog();
                    result = board.judgeWhoWinBy75();
                }
            }).start();
           
            endProgressDialog();
            new CalculateDlg(BoardAct.this, result).show();
           
            break;
        }

这样写的运行结果是点击完相关按钮以后,立马弹出了一个计算结果对话框,不过该对话框式空白,并没有显示结果,因为这时候result还是空,新开的线程还没有给
result赋值,所以主线程中显示result的值就为空,当关闭该对话框,重新再次打开对话框的时候显示的就是正确的result,不过还是没有出现进度条。自己还想到了
wait()和notify(),写了一下,也不行。


(三):
突然上网搜索了一下,用 handler
        case CALCULATE:
           
            new Thread(new Runnable() {
               
                @Override
                public void run() {
                    startProgressDialog();
                    result = board.judgeWhoWinBy75();
                   
                    handler.post(new Runnable()
                    {
                       
                        @Override
                        public void run()
                        {
                            endProgressDialog();
                            new CalculateDlg(BoardAct.this, result).show();
                           
                        }
                    });
                }
            }).start();
           
           
            break;
        }

这么写就达到了预期的效果,即点击计算以后,出现一个进度条对话框,当计算完以后,该进度条对话框关闭掉,并弹出来一个计算结果的对话框。
总结一下:这里无非就是两个线程的协作关系,当新生成的线程计算完结果以后,再通过handler告诉main线程关闭掉对话框,弹出计算结果的对话框,
而第二种之所以没有显示进度条对话框,我猜可能是新开的线程刚打开进度条对话框,main线程就给关了,是两个线程之间没有协作好;

而第一种情况,因为startProgressDialog()方法,endProgressDialog();的实现就是调用了handler,所以没出现进度条对话框的原因可能也是因为startProgressDialog()和
endProgressDialog()两个调用之间的间隔时间太短,所以没有看到。

如果把new CalculateDlg(BoardAct.this, result).show();放到handler.post(new Runnable() {}外边的话,就会报错,还是那个凡是跟UI有关的显示,关闭,都通过
handler.post()发给主线程来做,最好不要在主线程(UI线程)中做耗时的工作,因为这样容易阻塞用户界面。一般来说如果5秒钟没有响应,
android平台就会跳出界面未响应的对话框,这很不友好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值