说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Android开发进阶之NIO非阻塞包(八)

HTML文档下载 WORD文档下载 PDF文档下载
Android开发进阶之NIO非阻塞包(八)

作者:Android开发网


   在整个DDMS中体现Android NIO主要框架的要数MonitorThread.java这个文件了,有关PC和Android手机同步以及NIO非阻塞编程的精髓可以在下面的文件中充分体现出来。

  final class MonitorThread extends Thread {

    private static final int CLIENT_READY = 2;

    private static final int CLIENT_DISCONNECTED = 3;

    private volatile boolean mQuit = false;

    private ArrayList<Client> mClientList; //用一个数组保存客户端信息

    private Selector mSelector;

    private HashMap<Integer, ChunkHandler> mHandlerMap; //这里Android123提示大家,由于在多线程中concurrentHashMap效率比HashMap更安全高效,推荐使用并发库的这个替代版本。

    private ServerSocketChannel mDebugSelectedChan; //一个用于调试的服务器通道

    private int mNewDebugSelectedPort;

    private int mDebugSelectedPort = -1;

    private Client mSelectedClient = null;

    private static MonitorThread mInstance;

    private MonitorThread() {
        super("Monitor");
        mClientList = new ArrayList<Client>();
        mHandlerMap = new HashMap<Integer, ChunkHandler>();

        mNewDebugSelectedPort = DdmPreferences.getSelectedDebugPort();
    }

    static MonitorThread createInstance() {  //创建实例
        return mInstance = new MonitorThread();
    }

    static MonitorThread getInstance() { //获取实例
        return mInstance;
    }

    synchronized void setDebugSelectedPort(int port) throws IllegalStateException { //设置调试端口号
        if (mInstance == null) {
            return;
        }

        if (AndroidDebugBridge.getClientSupport() == false) {
            return;
        }

        if (mDebugSelectedChan != null) {
            Log.d("ddms", "Changing debug-selected port to " + port);
            mNewDebugSelectedPort = port;
            wakeup(); //这里用来唤醒所有的Selector
        } else {
            // we set mNewDebugSelectedPort instead of mDebugSelectedPort so that it's automatically
            mNewDebugSelectedPort = port;
        }
    }

    synchronized void setSelectedClient(Client selectedClient) {
        if (mInstance == null) {
            return;
        }

        if (mSelectedClient != selectedClient) {
            Client oldClient = mSelectedClient;
            mSelectedClient = selectedClient;

            if (oldClient != null) {
                oldClient.update(Client.CHANGE_PORT);
            }

            if (mSelectedClient != null) {
                mSelectedClient.update(Client.CHANGE_PORT);
            }
        }
    }

    Client getSelectedClient() {
        return mSelectedClient;
    }

    boolean getRetryOnBadHandshake() {
        return true; // TODO? make configurable
    }

    Client[] getClients() {
        synchronized (mClientList) {
            return mClientList.toArray(new Client[0]);
        }
    }

    synchronized void registerChunkHandler(int type, ChunkHandler handler) {
        if (mInstance == null) {
            return;
        }

        synchronized (mHandlerMap) {
            if (mHandlerMap.get(type) == null) {
                mHandlerMap.put(type, handler);
            }
        }
    }

    @Override
    public void run() { //本类的主要线程
        Log.d("ddms", "Monitor is up");

        try {
            mSelector = Selector.open();
        } catch (IOException ioe) {
            Log.logAndDisplay(LogLevel.ERROR, "ddms",
                    "Failed to initialize Monitor Thread: " + ioe.getMessage());
            return;
        }

        while (!mQuit) {

            try {
                synchronized (mClientList) {
                }

                try {
                    if (AndroidDebugBridge.getClientSupport()) {
                        if ((mDebugSelectedChan == null ||
                                mNewDebugSelectedPort != mDebugSelectedPort) &&
                                mNewDebugSelectedPort != -1) {
                            if (reopenDebugSelectedPort()) {
                                mDebugSelectedPort = mNewDebugSelectedPort;
                            }
                        }
                    }
                } catch (IOException ioe) {
                    Log.e("ddms",
                            "Failed to reopen debug port for Selected Client to: " + mNewDebugSelectedPort);
                    Log.e("ddms", ioe);
                    mNewDebugSelectedPort = mDebugSelectedPort; // no retry
                }

                int count;
                try {
                    count = mSelector.select();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                    continue;
                } catch (CancelledKeyException cke) {
                    continue;
                }

                if (count == 0) {
                    continue;
                } //这里代码写的不是很好,Android开发网提示大家因为这个NIO是DDMS工作在PC端的还不明显,这样轮训的在一个while中,效率不是很高,CPU很容易占用率很高。

                Set<SelectionKey> keys = mSelector.selectedKeys();
                Iterator<SelectionKey> iter = keys.iterator(); //使用迭代器获取这个选择键

                while (iter.hasNext()) {
                    SelectionKey key = iter.next();
                    iter.remove();

                    try {
                        if (key.attachment() instanceof Client) { //判断收到的key的附件是否是Client的实例
                            processClientActivity(key);
                        }
                        else if (key.attachment() instanceof Debugger) { //如果是Debug实例
                            processDebuggerActivity(key);
                        }
                        else if (key.attachment() instanceof MonitorThread) {
                            processDebugSelectedActivity(key);
                        }
                        else {
                            Log.e("ddms", "unknown activity key");
                        }
                    } catch (Exception e) {
                        Log.e("ddms", "Exception during activity from Selector.");
                        Log.e("ddms", e);
                    }
                }
            } catch (Exception e) {
                Log.e("ddms", "Exception MonitorThread.run()");
                Log.e("ddms", e);
            }
        }
    }

    int getDebugSelectedPort() {
        return mDebugSelectedPort;
    }

    private void processClientActivity(SelectionKey key) {
        Client client = (Client)key.attachment();

        try {
            if (key.isReadable() == false || key.isValid() == false) {
                Log.d("ddms", "Invalid key from " + client + ". Dropping client.");
                dropClient(client, true /* notify */);
                return;
            }

            client.read();

            JdwpPacket packet = client.getJdwpPacket();
            while (packet != null) {
                if (packet.isDdmPacket()) {
                    // unsolicited DDM request - hand it off
                    assert !packet.isReply();
                    callHandler(client, packet, null);
                    packet.consume();
                } else if (packet.isReply()
                        && client.isResponseToUs(packet.getId()) != null) {
                    // reply to earlier DDM request
                    ChunkHandler handler = client
                            .isResponseToUs(packet.getId());
                    if (packet.isError())
                        client.packetFailed(packet);
                    else if (packet.isEmpty())
                        Log.d("ddms", "Got empty reply for 0x"
                                + Integer.toHexString(packet.getId())
                                + " from " + client);
                    else
                        callHandler(client, packet, handler);
                    packet.consume();
                    client.removeRequestId(packet.getId());
                } else {
                    Log.v("ddms", "Forwarding client "
                            + (packet.isReply() ? "reply" : "event") + " 0x"
                            + Integer.toHexString(packet.getId()) + " to "
                            + client.getDebugger());
                    client.forwardPacketToDebugger(packet);
                }

                packet = client.getJdwpPacket();
            }
        } catch (CancelledKeyException e) { //注意正确处理这个异常
            dropClient(client, true /* notify */);
        } catch (IOException ex) {
            dropClient(client, true /* notify */);
        } catch (Exception ex) {
            Log.e("ddms", ex);

            dropClient(client, true /* notify */);

            if (ex instanceof BufferOverflowException) { //可能存在缓冲区异常
                Log.w("ddms",
                        "Client data packet exceeded maximum buffer size "
                                + client);
            } else {
                // don't know what this is, display it
                Log.e("ddms", ex);
            }
        }
    }

    private void callHandler(Client client, JdwpPacket packet,
            ChunkHandler handler) {

        // on first DDM packet received, broadcast a "ready" message
        if (!client.ddmSeen())
            broadcast(CLIENT_READY, client);

        ByteBuffer buf = packet.getPayload();
        int type, length;
        boolean reply = true;

        type = buf.getInt();
        length = buf.getInt();

        if (handler == null) {
            // not a reply, figure out who wants it
            synchronized (mHandlerMap) {
                handler = mHandlerMap.get(type);
                reply = false;
            }
        }

        if (handler == null) {
            Log.w("ddms", "Received unsupported chunk type "
                    + ChunkHandler.name(type) + " (len=" + length + ")");
        } else {
            Log.d("ddms", "Calling handler for " + ChunkHandler.name(type)
                    + " [" + handler + "] (len=" + length + ")");
            ByteBuffer ibuf = buf.slice();
            ByteBuffer roBuf = ibuf.asReadOnlyBuffer(); // enforce R/O
            roBuf.order(ChunkHandler.CHUNK_ORDER);
            synchronized (mClientList) {
                handler.handleChunk(client, type, roBuf, reply, packet.getId());
            }
        }
    }

    synchronized void dropClient(Client client, boolean notify) {
        if (mInstance == null) {
            return;
        }

        synchronized (mClientList) {
            if (mClientList.remove(client) == false) {
                return;
            }
        }
        client.close(notify);
        broadcast(CLIENT_DISCONNECTED, client);

        /*
         * http://forum.java.sun.com/thread.jspa?threadID=726715&start=0
         * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5073504
         */
        wakeup();
    }

    /*
     * Process activity from one of the debugger sockets. This could be a new
     * connection or a data packet.
     */
    private void processDebuggerActivity(SelectionKey key) {
        Debugger dbg = (Debugger)key.attachment();

        try {
            if (key.isAcceptable()) { //处理Server响应这个事件
                try {
                    acceptNewDebugger(dbg, null);
                } catch (IOException ioe) {
                    Log.w("ddms", "debugger accept() failed");
                    ioe.printStackTrace();
                }
            } else if (key.isReadable()) { //如果是收到的数据,则可读取
                processDebuggerData(key);
            } else {
                Log.d("ddm-debugger", "key in unknown state");
            }
        } catch (CancelledKeyException cke) { //记住,NIO处理这个异常,很多入门的开发者很容易忘记
            // key has been cancelled we can ignore that.
        }
    }

     private void acceptNewDebugger(Debugger dbg, ServerSocketChannel acceptChan) //这里用到了阻塞方式
            throws IOException {

        synchronized (mClientList) {
            SocketChannel chan;

            if (acceptChan == null)
                chan = dbg.accept();
            else
                chan = dbg.accept(acceptChan);

            if (chan != null) {
                chan.socket().setTcpNoDelay(true);

                wakeup();

                try {
                    chan.register(mSelector, SelectionKey.OP_READ, dbg);
                } catch (IOException ioe) {
                    // failed, drop the connection
                    dbg.closeData();
                    throw ioe;
                } catch (RuntimeException re) {
                    // failed, drop the connection
                    dbg.closeData();
                    throw re;
                }
            } else {
                Log.w("ddms", "ignoring duplicate debugger");
            }
        }
    }

    private void processDebuggerData(SelectionKey key) {
        Debugger dbg = (Debugger)key.attachment();

        try {
            dbg.read();

            JdwpPacket packet = dbg.getJdwpPacket();
            while (packet != null) {
                Log.v("ddms", "Forwarding dbg req 0x"
                        + Integer.toHexString(packet.getId()) + " to "
                        + dbg.getClient());

                dbg.forwardPacketToClient(packet);

                packet = dbg.getJdwpPacket();
            }
        } catch (IOException ioe) {
            Log.d("ddms", "Closing connection to debugger " + dbg);
            dbg.closeData();
            Client client = dbg.getClient();
            if (client.isDdmAware()) {
                   Log.d("ddms", " (recycling client connection as well)");

                    client.getDeviceImpl().getMonitor().addClientToDropAndReopen(client,
                        IDebugPortProvider.NO_STATIC_PORT);
            } else {
                Log.d("ddms", " (recycling client connection as well)");
                // we should drop the client, but also attempt to reopen it.
                // This is done by the DeviceMonitor.
                client.getDeviceImpl().getMonitor().addClientToDropAndReopen(client,
                        IDebugPortProvider.NO_STATIC_PORT);
            }
        }
    }

    private void wakeup() {
        mSelector.wakeup();
    }

    synchronized void quit() {
        mQuit = true;
        wakeup();
        Log.d("ddms", "Waiting for Monitor thread");
        try {
            this.join();
            // since we're quitting, lets drop all the client and disconnect
            // the DebugSelectedPort
            synchronized (mClientList) {
                for (Client c : mClientList) {
                    c.close(false /* notify */);
                    broadcast(CLIENT_DISCONNECTED, c);
                }
                mClientList.clear();
            }

            if (mDebugSelectedChan != null) {
                mDebugSelectedChan.close();
                mDebugSelectedChan.socket().close();
                mDebugSelectedChan = null;
            }
            mSelector.close();
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        mInstance = null;
    }

    synchronized void addClient(Client client) {
        if (mInstance == null) {
            return;
        }

        Log.d("ddms", "Adding new client " + client);

        synchronized (mClientList) {
            mClientList.add(client);

            try {
                wakeup();

                client.register(mSelector);

                Debugger dbg = client.getDebugger();
                if (dbg != null) {
                    dbg.registerListener(mSelector);
                }
            } catch (IOException ioe) {
                // not really expecting this to happen
                ioe.printStackTrace();
            }
        }
    }

    /*
     * Broadcast an event to all message handlers.
     */
    private void broadcast(int event, Client client) {
        Log.d("ddms", "broadcast " + event + ": " + client);

        /*
         * The handler objects appear once in mHandlerMap for each message they
         * handle. We want to notify them once each, so we convert the HashMap
         * to a HashSet before we iterate.
         */
        HashSet<ChunkHandler> set;
        synchronized (mHandlerMap) {
            Collection<ChunkHandler> values = mHandlerMap.values();
            set = new HashSet<ChunkHandler>(values);
        }

        Iterator<ChunkHandler> iter = set.iterator();
        while (iter.hasNext()) {
            ChunkHandler handler = iter.next();
            switch (event) {
                case CLIENT_READY:
                    try {
                        handler.clientReady(client);
                    } catch (IOException ioe) {
                        // Something failed with the client. It should
                        // fall out of the list the next time we try to
                        // do something with it, so we discard the
                        // exception here and assume cleanup will happen
                        // later. May need to propagate farther. The
                        // trouble is that not all values for "event" may
                        // actually throw an exception.
                        Log.w("ddms",
                                "Got exception while broadcasting 'ready'");
                        return;
                    }
                    break;
                case CLIENT_DISCONNECTED:
                    handler.clientDisconnected(client);
                    break;
                default:
                    throw new UnsupportedOperationException();
            }
        }

    }

    /**
     * Opens (or reopens) the "debug selected" port and listen for connections.
     * @return true if the port was opened successfully.
     * @throws IOException
     */
    private boolean reopenDebugSelectedPort() throws IOException {

        Log.d("ddms", "reopen debug-selected port: " + mNewDebugSelectedPort);
        if (mDebugSelectedChan != null) {
            mDebugSelectedChan.close();
        }

        mDebugSelectedChan = ServerSocketChannel.open();
        mDebugSelectedChan.configureBlocking(false); // required for Selector

        InetSocketAddress addr = new InetSocketAddress(
                InetAddress.getByName("localhost"), //$NON-NLS-1$
                mNewDebugSelectedPort);
        mDebugSelectedChan.socket().setReuseAddress(true); // enable SO_REUSEADDR

        try {
            mDebugSelectedChan.socket().bind(addr);
            if (mSelectedClient != null) {
                mSelectedClient.update(Client.CHANGE_PORT);
            }

            mDebugSelectedChan.register(mSelector, SelectionKey.OP_ACCEPT, this);

            return true;
        } catch (java.net.BindException e) {
            displayDebugSelectedBindError(mNewDebugSelectedPort);

            // do not attempt to reopen it.
            mDebugSelectedChan = null;
            mNewDebugSelectedPort = -1;

            return false;
        }
    }

    /*
     * We have some activity on the "debug selected" port. Handle it.
     */
    private void processDebugSelectedActivity(SelectionKey key) {
        assert key.isAcceptable();

        ServerSocketChannel acceptChan = (ServerSocketChannel)key.channel();

        /*
         * Find the debugger associated with the currently-selected client.
         */
        if (mSelectedClient != null) {
            Debugger dbg = mSelectedClient.getDebugger();

            if (dbg != null) {
                Log.d("ddms", "Accepting connection on 'debug selected' port");
                try {
                    acceptNewDebugger(dbg, acceptChan);
                } catch (IOException ioe) {
                    // client should be gone, keep going
                }

                return;
            }
        }

        Log.w("ddms",
                "Connection on 'debug selected' port, but none selected");
        try {
            SocketChannel chan = acceptChan.accept();
            chan.close();
        } catch (IOException ioe) {
            // not expected; client should be gone, keep going
        } catch (NotYetBoundException e) {
            displayDebugSelectedBindError(mDebugSelectedPort);
        }
    }

    private void displayDebugSelectedBindError(int port) {
        String message = String.format(
                "Could not open Selected VM debug port (%1$d). Make sure you do not have another instance of DDMS or of the eclipse plugin running. If it's being used by something else, choose a new port number in the preferences.",
                port);

        Log.logAndDisplay(LogLevel.ERROR, "ddms", message);
    }
}

  从上面来看Android的开源代码有关PC上的写的不是很好,很多实现的地方都是用了严重的缝缝补补方式解决,有些习惯不是很到位,有关本NIO例子由于涉及的项目对象多,理解需要网友深入分析DDMS源码中的每个对象。细节写的不是很理想,Android123推荐大家,画出UML后再分析更清晰。

转战中小型企业:Prediction API请求一个月内飙升至7亿多次 利用光子 耶鲁大学研究人员让量子计算机离现实更近一步 技术为王的云计算会让IT部门消亡么? 从Discuz到APP:安米移动社区转化工具 覆盖全领域:Google、Facebook、Twitter等大师的最佳推荐 苹果CEO宣布更改保修政策 并向中国用户道歉 拒绝使用现有Web组件的6个愚蠢理由 Github宣布支持SVN方式访问 iPad,正在改变什么? Go Mobile:行业大牛谈行业应用开发 亚马逊Cloud Drive新增文件同步功能 对抗Dropbox 35万奖金发放,BlackBerry 10大赛奖项揭晓 超越Google Apps:排行榜前10的相关云应用 荣耀终将消散 全球第一台千万亿次级超级计算机退役 谷歌已推免费Android和iPhone版Quickoffice,微软你呢? 用于响应式设计的9个CSS技巧 微软Surface Pro正式登陆中国市场 售价6588元起 岳雷:Windows Server 2012虚拟化性能提升巨大 陈健:Windows Server 2012让企业轻松管理IT 智能手机:革命已经波及到阴间 兄贵草泥马:重口味单机移动游戏为什么能火? 最炫HTML5框架Famo.us 将免费面向开发者 MySQL到NoSQL:数据的重思和查询方式的转换 程序员心髓:移动应用API设计10大技巧 Netflix公布个性化和推荐系统架构,3种类型作业通实时 从SendCloud到搜狐云 扎克伯格的败笔?Facebook Home可能无家可归 走进eico design,仰视设计师 乔布斯顾问承认苹果的命名糟透了 罗永浩:一百万年薪!招聘软件研发总监 开源的:helios移动应用后端服务框架 转换类型 COM的问题(新手) 如何应用ASF Reader Filter? 关于接收windows消息的问题 java程序移植到linux下中文字体变成??||之类的,怎么解决 怎么近来CSDN上的N多历史帖子都看不了了 ? 如何获取汉字的拼音码? 有没有记录DBGrid的当前位置的,我说的不是用bookmark,因为我的DataSet是动态建立的,在刷新时好象Bookmark用不了。 英文cuteftp为何中文显示为乱码? 汉化cuteftp却显示英文为乱码? 这个问题真头疼! 在XML中,如何显示一个图像 编程菜鸟急急急——关于autocad的一个插件!! winxp家庭版中是否有IIS,有的话在哪里安装,我在添加windows组件中怎么找不到?在线! js中有没有类似php中的basename 和 explode 方法 hook 问题? help,我一哥们光荣下岗,有做java项目又缺pm的请帮忙 简单问题,怎么才能把这个函数的返回值转换成字符串放在一edit1.text中。50分 关于控制窗口的问题! 如何关闭数据库连接? 救命!!WINDOWS启动错误 Java应用程序,汉字显示成方格...... 高手请进 高手请进 开发的结局,一个美丽的谎言!!! 发邮件! 请问! 请问各位高手:汉字转换为拼音,怎么转换? 如何模拟窗口最小化? 怎样才能最有效率的得知RESULTSET对象中没有记录呢? 有谁知道PC104的结构,芯片,CPU等的情况,和适合开发什么应用? MFC dll中 一用了ActiveMovieControl别的程序就不能调用了,怎么解决? 如何在BCB中建立视图? 那天,我被扎了一针 rad hat能不能与windos联机啊、? 惨啊,要跳楼了,谁能帮忙,关于内存泄漏的问题 请问在那里下载VtoolsD开发工具? 为什么ASP页面总是报“HTTP 500 - 内部服务器错误 ” 請問:TC2.0中有無類似于API GetPrivateProfileString()的函數? VB 中如何判断一个对象变量是否被赋值 请问作为标识字段用什么格式好?见者有分!!!! 诚心求教:MDI多视图之间的成员函数调用问题。 请推荐一些有关.net平台的优秀书籍 加密字符串的问题 win2000下无法正常使用localhost来浏览asp页? ★★★如何将一个数字转换成英文写法?急急急!!!★★★ 关于FTP站点下载得问题。。。 STL中有没有左高树?或者菲薄那契堆? 目前,主流的B/S结构的数据库前端开发工具是什么?哪个最有前途? 给我个喜欢VC放JAVA的理由先! 如何解决两个tabpage互换时,tabpage上的控件因检索大量数据而闪烁。 有关dll在设备驱动中的问题。急,在线等待。多谢多谢!! 一个字符串常量"aaa=",一个字符串指针char *m_buffer="bbb",怎样相加得到"aaa=bbb".谢谢! 两辆汽车在同一平直路面上行驶,他们的质量之比m1:m2=1:2速度之比v1:v2=2:1,当两车急刹车后,甲车滑行的最大距离为l1,一车华星的最大距离为l2,设两车与路面间的动摩擦因数相等,不计空 大白兔和金丝猴(奶糖)哪一个更好? 买超滤净水机呢还是RO膜净水机呢?超滤的便宜,RO的技术先进,过滤效果一级棒,可是好贵啊!纠结中~ 中南海凭什么不让进人民的土地不让人民进去 喔喔奶糖与金丝猴奶糖哪种好吃?觉得哪种好吃啊? 金丝猴奶糖和大白兔有什么不同? 怎么才能进中南海? 两辆汽车在同一水平路面上行驶,它们的质量之比为m1:m2=1:2,速度之比为v1:v2=2:1,当汽车急刹车后,甲、乙两辆车滑行的最大距离为s1和s2,若两车与路面的动摩擦因数相同,且不计空气阻力,则A.s1 当90°≤α≤180°时,方程x^2cosα+y^2sinα=1表示怎样的曲线 如果你的单位有人说自己进过中南海,你会怎么办?不理他默默恨他给他生事联合别人整走他 一元二次方程ax^2+2x+1=0且a不等于0,有一正根和一负根的充分不必要条件是? 为什么温带气旋多出现在春秋季节? 怎样进入直通中南海留言板 一元二次方程ax^2+2x+1=0,a不等于0,有一正根一负根充分不必要条件 当α从0°到180°变化时,方程x^2cosα+y^2sinα=1表示的曲线方程变化 关于x的方程二之一的x次方 等于五加2a分之2a加三有负根求实数a的取值范围 运动员将足球从后场踢到前场,足球在空中运动的过程中,不计空气阻力,为什么只受重力 温带气旋出现的时间或者季节 2000克的18%的糖水里加入多少千克水后,变成含糖12%的水? 踢出去的足球 在空中运动时 若不记空气阻力 它的受力情况是A只受到重力B既受重力 它的受力情况时 α在[0,2π] 方程x^2cosα+y^2sinα=1表示怎样的曲线? 2000克的18%的糖水里加入多少克水后,变成含糖12%的糖水?快,最好赶在明天之前.一定要对,还要说明意思.我会重金悬赏的.是糖水!我的问题是糖水!糖水,亲们 已知x的一元二次方程ax+bx+c=0有两个不等于零的实数根,求一个一元二次方程,使他的根分别是已知方程根的倒数 关于x、y的方程x^2sinθ+y^2cosθ=tanθ(θ∈(π/2,π))的曲线是双曲线,则它的实轴长等于? 小明用100牛的力水平推动木箱以2米每秒的速度向右做匀速直线运动,则木箱所受摩擦力的大小是( )牛.若要使木箱以5米每秒的速度向右做匀速直线运动,则人的推力的大小应是( )牛,木箱所受摩 金丝猴奶糖很好吃吗? 英国和日本哪个国土面积大. 用100牛的水平向右的力推着300牛的木箱在地面上做匀速直线运动.求木箱受到的大小和方向 英国国王或女王、日本的天皇是不是和中国历代的皇帝一样,经历了许多朝代 为社么海洋21世纪的希望? 一元二次方程ax∧2+2x+1=0(a≠0)有一个正根和一个负根的充分不必要条件是()A.a<0 B.a>0 C.a<-1 D.a>1高手们能不能写写思路呢?正确答案是C 2012又2010分之一等于2012加2010分之一吗 75G反渗透纯水机净水器RO流体膜FS-TFC-1812-50中的 FS和TFC分别指的是什么意思? 一元二次方程ax²+2x+1=0(a不等于0)有一正根和一负根的充分不必要条件是Aa 汽车A沿着平直的公路以速度v做匀速直线运动,当A路过P点时,汽车B从P点开始做初速度为0,加速度为a的匀加速直线运动去追赶A车 求(1)汽车B经过多长时间追上A车 (2)追上A车时,汽车B的速度 ro反渗透膜纯水机出水率一般是多少 一元二次方程ax+bx+c=0(a不等于0)有一个正根和一个负根的充分不必要条件是A.a>0Ba<0Ca<-1Da>1为什么 汽车在平直公路上行驶,在它的速度为零增加到V的过程中.汽车在平直公路上行驶,在它的速度为零增加到V的过程中,汽车发动机做功W1.在它的速度由V增到2V的过程中发动机做功为W2,设汽车的牵 大熊猫,扬子鳄,金丝猴,孔雀,那个不是我国特有的 一元二次方程ax^2+2x+1=0有一个正根和一个负根的充分不必要条件是? (A)a0 (C)a1为什么选C必要和充分条件的关系,通俗点说是区别(怎么用集合来表示必要不充分和充分不必要条件,或者用命题真假 质量为吗的汽车在平直公路上以速度v如果匀速,牵引力做的功=阻力做的功加速,就?、对了?这样理解还有一个问题,机械能的增加与减少,与物体加速,减速有关吗? 一辆汽车以速度V1匀速行驶全程的2/3的路程,接着以V2=20Km/h走完剩下的路程,若全路程的平均速度V=28Km/h我知道结果是35km/h可是老是算不出来要求运算的全过程,就是28km/h=s/(2s/3/V1+s/3/v2)结果是35k 克里姆林宫的英文是什么?英文全写,外加英标. 英国时间现在是几日几点几分现在的北京时间是9:04 超滤和ro反渗透净水器,家庭用,哪个好? 克里姆林宫在哪里 日本为什么称为日不落帝国?不落的太阳 请问净水器里超滤的和反渗透的有什么区别?具体在哪里? 克里姆林宫在哪 金丝猴的奶糖好吃还是大白兔的好吃? 13、海洋——21世纪的希望分段怎么分?段意? 甲乙两辆汽车在同一平直的路上行驶,它们的质量比为m1:m2=1:2,速度比为v1:v2=2:1.当两车急刹车后,甲车滑行的最大距离为S1,乙车滑行的最大距离为S2,设两车与地面的动摩擦因素相等,不计空气阻 在平直公路上,一自行车与同向行驶的汽车同时经过某点,它们的位移随时间的变化关系...11.在平直公路上,一自行车与同向行驶的汽车同时经过某点,它们的位移随时间的变化关系分别是:自 现在一台天平,只有3个分别是3克·9克和11克的法码,要求你一次就能称出17克的黄金来,怎么称?写出式子. 大白兔和金丝猴奶糖哪一个更好吃?阐述理由如题. 在平直公路上,一自行车与同向形势的汽车同时经过某点,它们的位移随时间变化的关系是在平直公路上,一自行车与同向形势的汽车同时经过某点,它们的位移随时间变化的关系是:自行车x1=6t, 锋面气旋为何易在温带形成 克里姆林宫在哪个国家? 英国的君主立宪制和日本的君主立宪制有什么相同点和不同点? 如何分辨锋面气旋
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘