[Android] Android adb push是怎样被实现的?

Android adb push是怎样被实现的?

CODE: commandline.c
PATH: <ANDROID_PROJECT>/system/core/adb/commandline.c
FUNC: do_sync_push() @adb_commandline()
LINE: 1147
-
do_sync_push() body is at 
@ <ANDROID_PROJECT>/system/core/adb/file_sync_client.c
-
int  do_sync_push(  const  char  *lpath,  const  char  *rpath,  int  verifyApk)
{
     struct  stat st;
     unsigned  mode;
     int  fd;

   fd = adb_connect( "sync:" );

     if (fd < 0) {
        fprintf(stderr,  "error: %s\n" , adb_error());
         return  1;
    }

     if (stat(lpath, &st)) {
        fprintf(stderr,  "cannot stat '%s': %s\n" , lpath, strerror(errno));
        sync_quit(fd);
         return  1;
    }

     if (S_ISDIR(st. st_mode )) {
        BEGIN();
         if (copy_local_dir_remote(fd, lpath, rpath, 0, 0)) {
             return  1;
        }  else  {
            END();
            sync_quit(fd);
        }
    }  else  {
         if (sync_readmode(fd, rpath, &mode)) {
             return  1;
        }
         if ((mode != 0) && S_ISDIR(mode)) {
                 /* if we're copying a local file to a remote directory,
                ** we *really* want to copy to remotedir + "/" + localfilename
                */
             const  char  *name = adb_dirstop(lpath);
             if (name == 0) {
                name = lpath;
            }  else  {
                name++;
            }
             int   tmplen = strlen(name) + strlen(rpath) + 2;
             char  *tmp = malloc(strlen(name) + strlen(rpath) + 2);
             if (tmp == 0)  return  1;
            snprintf(tmp, tmplen,  "%s/%s" , rpath, name);
            rpath = tmp;
        }
        BEGIN();
         if (sync_send(fd, lpath, rpath, st. st_mtime  , st. st_mode  , verifyApk)) {
             return  1;
        }  else  {
            END();
            sync_quit(fd);
             return  0;
        }
    }

     return  0;
}

-
接着查看sync_send()函数的实现部分
-
@ <ANDROID_PROJECT>/system/core/adb/file_sync_client.c
L 297
-
static  int  sync_send ( int  fd,  const  char  *lpath,  const  char  *rpath,
                      unsigned  mtime, mode_t mode,  int  verifyApk)
{
    syncmsg msg;
     int  len, r;
     syncsendbuf  *sbuf = &send_buffer;
     char * file_buffer = NULL;
     int  size = 0;
     char  tmp[64];

    len = strlen(rpath);
     if (len > 1024)  goto  fail;

    snprintf(tmp,  sizeof (tmp),  ",%d" , mode);
    r = strlen(tmp);

     if  (verifyApk) {
         int  lfd;
        zipfile_t zip;
        zipentry_t entry;
         int  amt;

         // if we are transferring an APK file, then sanity check to make sure
         // we have a real zip file that contains an AndroidManifest.xml
         // this requires that we read the entire file into memory.
        lfd = adb_open(lpath, O_RDONLY);
         if (lfd < 0) {
            fprintf(stderr,  "cannot open '%s': %s\n" , lpath, strerror(errno));
             return  -1;
        }

        size = adb_lseek(lfd, 0, SEEK_END);
         if  (size == -1 || -1 == adb_lseek(lfd, 0, SEEK_SET)) {
            fprintf(stderr,  "error seeking in file '%s'\n"  , lpath);
            adb_close(lfd);
             return  1;
        }

        file_buffer = (  char  *)malloc(size);
         if  (file_buffer == NULL) {
            fprintf(stderr,  "could not allocate buffer for '%s'\n"  ,
                    lpath);
            adb_close(lfd);
             return  1;
        }
        amt = adb_read(lfd, file_buffer, size);
         if  (amt != size) {
            fprintf(stderr,  "error reading from file: '%s'\n"  , lpath);
            adb_close(lfd);
            free(file_buffer);
             return  1;
        }

        adb_close(lfd);

        zip = init_zipfile(file_buffer, size);
         if  (zip == NULL) {
            fprintf(stderr,  "file '%s' is not a valid zip file\n" ,
                    lpath);
            free(file_buffer);
             return  1;
        }

        entry = lookup_zipentry(zip,  "AndroidManifest.xml" );
        release_zipfile(zip);
         if  (entry == NULL) {
            fprintf(stderr,  "file '%s' does not contain AndroidManifest.xml\n"  ,
                    lpath);
            free(file_buffer);
             return  1;
        }
    }

    msg.req.id = ID_SEND;
    msg.req.namelen = htoll(len + r);


     if (writex(fd, &msg.req,  sizeof (msg.req)) ||
       writex(fd, rpath, len) || writex(fd, tmp, r)) {
        free(file_buffer);
         goto  fail;
    }


     if  (file_buffer) {
        write_data_buffer(fd, file_buffer, size, sbuf);
        free(file_buffer);
    }  else  if  (S_ISREG(mode))
        write_data_file(fd, lpath, sbuf);
#ifdef  HAVE_SYMLINKS
     else  if  (S_ISLNK(mode))
        write_data_link(fd, lpath, sbuf);
#endif
     else
         goto  fail;

    msg.data.id = ID_DONE;
    msg.data.size = htoll(mtime);
     if (writex(fd, &msg.data,  sizeof (msg.data)))
         goto  fail;

     if (readx(fd, &msg.status,  sizeof (msg.status)))
         return  -1;

     if (msg.status.id != ID_OKAY) {
         if (msg.status.id == ID_FAIL) {
            len = ltohl(msg.status.msglen);
             if (len > 256) len = 256;
             if (readx(fd, sbuf-> data  , len)) {
                 return  -1;
            }
            sbuf->  data [len] = 0;
        }  else
            strcpy(sbuf->  data ,  "unknown reason" );

        fprintf(stderr,  "failed to copy '%s' to '%s': %s\n"  , lpath, rpath, sbuf-> data );
         return  -1;
    }

     return  0;

fail:
    fprintf(stderr, "protocol failure\n" );
    adb_close(fd);
     return  -1;
}

### 回答1: Android可以通过adb push从电脑复制文件。ADBAndroid Debug Bridge的缩写,它是一种用于与Android设备通信的命令行工具。通过ADB,用户可以在电脑上执行各种与设备相关的操作,例如调试应用程序和复制文件。 要使用ADB push从电脑复制文件到Android设备,首先需要确保设备已连接到电脑上并已启用开发者选项。然后在命令行中输入“adb push [本地文件路径] [目标文件路径]”,其中,[本地文件路径]为要复制的文件在电脑上的路径,[目标文件路径]为要将文件复制到的Android设备上的路径。 例如,如果要将名为“test.txt”的文件复制到Android设备的“/sdcard/”目录下,可以在命令行中输入以下命令: adb push C:\test.txt /sdcard/test.txt 执行完上述命令后,文件就会被复制到Android设备中指定的目录下。通过ADB push,用户可以方便地将文件从电脑复制到Android设备中,从而实现数据共享和文件传输等功能。 ### 回答2: Android系统是目前移动端最流行的操作系统之一,其中adb命令作为Android Debug Bridge的缩写,主要用于Android设备的调试、升级和管理等功能,是Android开发中的重要工具之一。在开发过程中,我们可以利用adb push指令来实现从电脑往Android设备上传文件的目的,这是adb指令中最常用的一种操作。 具体来说,adb push指令可以帮助我们将本地文件上传到Android设备中的指定目录当中。使用该指令需要指定上传源文件和目标目录,指令格式如下: adb push <源文件路径> <目标目录> 其中,源文件路径指的是电脑中待上传的文件路径,而目标目录则指的是Android设备中的目标文件夹路径。使用时,我们需要将Android设备与电脑通过USB连接起来,并在电脑端打开命令行窗口(或者终端),然后输入上述指令即可。 需要注意的是,使用adb push指令前,我们需要确保Android设备已开启USB调试模式,并且电脑已经安装好了adb驱动程序。此外,如果目标目录不存在,则需要在目标目录的上一级目录创建该文件夹。 综上所述,通过adb push指令,我们可以很方便地将本地文件上传到Android设备中,实现数据传输和管理的目的。当然,在使用该指令时需要注意相关的前置条件和细节。 ### 回答3: Android系统可以通过adb push命令从电脑复制文件。Android Debug Bridge(ADB)是一个由Google开发的工具集,它允许电脑和Android设备之间建立连接,从而使开发者能够在电脑上通过命令行与设备交互。在使用adb push命令时,需将文件拷贝到电脑的ADB工具路径下,即可以使用cmd或终端窗口进行下列操作。 首先需要在电脑上打开命令行(Windows)或者终端(macOS或Linux),进入ADB工具路径(一般在SDK安装目录下platform-tools目录中),连接Android设备,然后使用adb push命令,语法格式如下: adb push <源文件路径> <终点文件路径> 其中,源文件路径指的是要复制的文件在电脑上的路径,终点文件路径指的是要将该文件复制到Android设备上的路径。例如,要将电脑上的music.mp3文件复制到Android设备的SD卡根目录下,可以使用下面的命令: adb push D:\music.mp3 /sdcard/ 这样,电脑上的music.mp3文件就会被复制到Android设备的SD卡根目录下。 需要注意的是,在使用adb push命令之前,需要保证ADB已正确的安装在电脑上并且设备已正确连接到电脑。此外,在使用ADB命令时还需要仔细查看ADB版本与设备的兼容性。在遇到异常情况时,可以通过adb help查看帮助文档或者参考ADB的官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值