精华内容
参与话题
问答
  • 在编程中,很多时候,不仅需要程序内部需要共享/传递数据(如同一个thread,或是不同的thread),不同程序之间(process)也经常需要共享数据。 在Linux系统中,我们经常用到的Linux命令,如"ls -al",其中"-al"是...

    在编程中,很多时候,不仅需要程序内部需要共享/传递数据(如同一个thread,或是不同的thread),不同程序之间(process)也经常需要共享数据。

    在Linux系统中,我们经常用到的Linux命令,如"ls -al",其中"-al"是传给application “ls”的输入值,下面的数据是"ls"的输出值。Linux下的不同程序间传递数据十分直接明了,而Android则不同。

    $ ls -al
    total 180972
    drwxr-xr-x 1 K0402004 1049089         0 八月   16 14:58 ./
    drwxr-xr-x 1 K0402004 1049089         0 八月    6 11:38 ../
    -rw-r--r-- 1 K0402004 1049089  68425872 八月    3 16:46 gradle-2.10-all.zip
    -rw-r--r-- 1 K0402004 1049089 116851656 八月    1 16:37 gradle-4.10.1-all.zip
    

    对于Android而言,则采取不同的方式,采用"intent"进行交互。整理如下,

    1. A程序呼叫B程序,并且传递数据给B数据

    首先新建一个intent,然后把“Component”赋值给intent;如果要传递值,则放在“putExra”中;最后呼叫“startActivityForResult”

    packageName = "com.xxx.sensor";
    activityName = "com.xxx.sensor.IRSensorTest";
    mTestItemComponentName = new ComponentName(packageName,activityName);
    
    Intent intent = new Intent();
    intent.setComponent(mTestItemComponentName);
    intent.putExtra("TESTSTYLE", "Test");
    intent.putExtra("LANGUAGE", "English");
    startActivityForResult(intent, REQUEST_CODE);

    2. Activity B则可以在onCreate()方法中获得Activity A传入的数据,

    Intent intent = getIntent();
    String testStyle = intent.getStringExtra("TESTSTYLE");
    String language = intent.getStringExtra("LANGUAGE");

    3. Activity B结束时,可以向Activity A传入返回值,比如测试结果,

    (Activity A在启动Activity B的时候需要呼叫“startActivityForResult()”,而不能只呼叫“startActivity()”)

        public void returnWithResult(Activity curActivity, boolean isPass) {
            Intent intent = new Intent();
            intent.putExtra("result", isPass);
            curActivity.setResult(-1, intent);
            curActivity.finish();
        }

    4. Activity A获取从Activity B传来的数据, 需要在方法“onActivityResult()”中获取,

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            // TODO Auto-generated method stub
            super.onActivityResult(requestCode, resultCode, data);
            if (data != null) {
                mReturnResult = data.getBooleanExtra("result", false);
            }
            。。。。

    实际开发中,不同Activity之间的数据传递还是十分经常出现的,谨此记之。

     

     

     

     

     

     

     

    展开全文
  • Activity和Service的交互方式

    千次阅读 2017-06-04 02:31:45
    使用Service在后台进行音乐播放,前台使用Activity显示界面,点击前台控件后需要告知Service,控制音乐的播放、暂停、切换下一首等,后台Service再将数据传给Activity来改变界面显示Activity和Service的交互方式主要...

    在开发过程中,经常会遇到Activity和Service进行相互通信、交换数据的需要,最常见的比如音乐播放器,使用Service在后台进行音乐播放,前台使用Activity显示界面,点击前台控件后需要告知Service,控制音乐的播放、暂停、切换下一首等,后台Service再将数据传给Activity来改变界面显示

    Activity和Service的交互方式主要有以下几种

    • 通过广播进行交互
    • 通过共享文件
    • Messenger
    • AIDL

    下面分别使用几种交互方式来实现一个计时器的程序,程序界面只有一个Button,Button上显示一个数字,点击Button后开始计时,每隔1秒,Button上数据加1,使用Service来实现计时的功能

    布局文件很简单

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <Button
            android:id="@+id/start"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
    </RelativeLayout>

    1、通过广播交互

    在Activity中点击Button后启动Service

    public void onClick(View v) {
            Intent intent = new Intent(this, CounterService.class);
            intent.putExtra("counter", counter); //counter用来计数
            startService(intent);
        }

    CounterService.java

    public class CounterService extends Service {
    
        int counter;
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // TODO Auto-generated method stub
            counter = intent.getIntExtra("counter", 0);
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    Intent counterIntent = new Intent();
                    counterIntent.putExtra("counter", counter);
                    counterIntent.setAction("com.example.counter.COUNTER_ACTION");
                    sendBroadcast(counterIntent);
                    counter++;
                }
            }, 0, 1000);
            return START_STICKY;
        }
    
    }

    在Service的onStartCommand()中启动一个定时器,每隔1秒钟counter计数加1,通过广播发送将counter发送出去,在Activity中收到广播后取出counter,将counter设置到Button上

    广播接收器,定义在Activity中

    class CounterReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                // TODO Auto-generated method stub
                counter = intent.getIntExtra("counter", 0);
                start.setText(counter + "");
            }
        }

    运行程序,点击按钮开始计时

    这里写图片描述

    在程序运行过程遇到一个问题,在这里说明一下,广播类是在Activity里定义的,是Activity的内部类,这个内部类在使用静态注册的时候,会发生程序运行崩溃,原因是内部广播类如果使用静态注册,必须是静态内部类,但是如果是静态内部类,只能访问外部类的静态成员变量,所以内部广播类推荐使用动态注册方式,而且这类广播一般只在程序内部使用,没有必须在进程结束以后继续接收广播

    通过广播实现Activity和Service的交互简单容易实现,缺点是发送不广播受系统制约,系统会优先发送系统级的广播,自定义的广播接收器可能会有延迟,在广播里也不能有耗时操作,否则会导致程序无响应

    2、通过共享文件

    共享文件就是通过读写同一个文件来进行通信,使用这种方式通信时,同一时间只能一方写,一方读,不能两方同时写,这里使用SharedPreferences来实现Activity和Service的交互

    客户端点击Button启动Service

    public void onClick(View v) {
            Intent intent = new Intent(this, CounterService.class);
            intent.putExtra("counter", counter); //counter用来计数
            startService(intent);
        }

    CounterService.java

    public class CounterService extends Service {
    
        int counter;
        SharedPreferences sharedPreferences;
    
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // TODO Auto-generated method stub
            counter = intent.getIntExtra("counter", 0);
            sharedPreferences = getSharedPreferences("counter_preferences", Context.MODE_PRIVATE);
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    sharedPreferences.edit().putInt("counter", counter).commit();
                    counter++;
                }
            }, 0, 1000);
            return START_STICKY;
        }
    
    }

    在Service中同样启动一个定时器,每秒将计数加1,然后写入到SharedPreferences中

    在Activity中也需要启动一个定时任务,从SharedPreferences中读取计数

    sharedPreferences = getSharedPreferences("counter", Context.MODE_PRIVATE);
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    counter = sharedPreferences.getInt("counter", 0);
                    handler.sendEmptyMessage(0x123);
                }
            }, 0, 1000);

    在Activity的onCreate()中启动定时器,每隔1秒读取一次数据,由于在子线程中是无法更新UI的,所以通过handler发送一条消息到主线程中更新

    Handler handler = new Handler() {
            public void handleMessage(android.os.Message msg) {
                if(msg.what == 0x123) {
                    start.setText(counter + "");
                }
            };
        };

    程序运行结果和上图相同

    使用SharedPreferences进行数据共享对文件格式没有要求,只要读写双方约定好数据格式即可。但是也有局限性,在面对高并发的读写时,这种方式就变得不可靠,很可能会导致读写的数据不一致,所以不建议使用这种方式来进行通信

    3、Messenger

    Messenger的意思可以译为信使,通过它可以在不同进程间传递Meesage对象,Messenger是一种轻量级的IPC方案,底层是用AIDL实现的

    使用Messenger在Activity和Service之间进行数据传输的步骤如下;

    1、在Service端创建信使对象

    创建Messenger需要传入一个Handler对象,所以首先要新建一个Handler,利用Handler来创建信使

    @Override
        public void onCreate() {
            // TODO Auto-generated method stub
            super.onCreate();
            mMessenger = new Messenger(handler);
        }

    2、Service端的onBind()方法使用mMessenger.getBinder()返回一个binder对象

    @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return mMessenger.getBinder();
        }

    3、客户端绑定到Service,在onServiceConnected()方法中使用Service返回的IBinder对象创建Messenger对象,通过这个Messenger对象就可以向Service发送消息了。

    ServiceConnection connection = new ServiceConnection() {
            public void onServiceConnected(ComponentName name, android.os.IBinder service) {
                rMessenger = new Messenger(service);
            };
            public void onServiceDisconnected(ComponentName name) {
    
            };
        };

    这样只是实现了客户端向Service发送消息,如果需要Service可以将相应客户端,同样的需要在客户端使用Handler来创建Messenger对象,通过Message将这个Messenger传到Service中,Service获取到客户端的Messenger对象后,也可以向客户端发送消息。

    通过Messenger来实现上面的功能

    Service端的代码CounterService.java

    public class CounterService extends Service {
    
        int counter;
        Messenger mMessenger, cMessenger; //Service的信使对象和客户端的信使对象
    
        Handler handler = new Handler() {
            public void handleMessage(Message msg) {
                cMessenger = msg.replyTo; //获取Message中的客户端信使对象
                counter = msg.arg1; //获取Message中的计数
                new Timer().schedule(new TimerTask() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        Message message = Message.obtain();
                        message.arg1 = counter;
                        try {
                            cMessenger.send(message); //通过客户端的信使对象向客户端发送消息,消息中保存counter
                        } catch (RemoteException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        counter++;
                    }
                }, 0, 1000);
            };
        };
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return mMessenger.getBinder();
        }
    
        @Override
        public void onCreate() {
            // TODO Auto-generated method stub
            super.onCreate();
            mMessenger = new Messenger(handler); //初始化Service信使
        }
    
    }

    客户端代码MainActivity.java

    public class MainActivity extends Activity {
    
        Button start;
        int counter = 0;
        Messenger rMessenger, mMessenger; //远程Service端的信使对象和客户端本地的信使对象
    
        Handler handler = new Handler() {
            public void handleMessage(Message msg) {
                counter = msg.arg1; //获取Service消息中的计数
                start.setText(counter + "");
            };
        };
    
        ServiceConnection connection = new ServiceConnection() {
            public void onServiceConnected(ComponentName name, IBinder service) {
                rMessenger = new Messenger(service); //使用Service返回的IBinder对象初始化Service端信使对象
                mMessenger = new Messenger(handler); //初始化本地客户端信使对象
                Message message = Message.obtain();
                message.replyTo = mMessenger; //将客户端的信使对象保存到message中,通过Service端的信使对象发送给Service
                message.arg1 = counter;
                try {
                    rMessenger.send(message);
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            };
            public void onServiceDisconnected(ComponentName name) {
                rMessenger = null;
            };
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            start = (Button)findViewById(R.id.start);
            start.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Intent intent = new Intent(MainActivity.this, CounterService.class);
                    bindService(intent, connection, BIND_AUTO_CREATE);
                }
            });
        }
    
    }

    代码中的注释很详细,点击按钮后,客户端绑定到Service,通过Service中返回的IBinder对象创建Service端的信使对象,然后将客户端本地的信使对象和计数变量通过Message发送到Service中。

    在Service中获取到客户端发送过来的消息后,取出信息中的Messenger,这样Service中就有了客户端的信使对象,就可以向客户端发送消息,这样就实现了双向通信。

    程序运行效果和前面两个程序一样

    4、使用AIDL进行通信

    AIDL属于Android的IPC机制,常用于跨进程通信,主要实现原理基于底层Binder机制,使用AIDL Service实现进程间通信在另一篇博客http://blog.csdn.net/zh175578809/article/details/71915238中有详细介绍,这里就不再阐述

    展开全文
  • Activity之间的交互

    2016-06-05 00:58:49
    一、不同App直接Activity的调用 1、当不同的App直接进行调用Intent的声明需要隐式声明 2、在调用之前需要检查是否有App能够接收否则会引起CrashPackageManager packageManager = getPackageManager(); List ...

    一、不同App直接Activity的调用

    1、当不同的App直接进行调用Intent的声明需要隐式声明
    2、在调用之前需要检查是否有App能够接收否则会引起Crash

    PackageManager packageManager = getPackageManager();
    List activities = packageManager.queryIntentActivities(intent,
            PackageManager.MATCH_DEFAULT_ONLY);
    boolean isIntentSafe = activities.size() > 0;

    3、当有多个满足条件的Intent出现时,回跳出列表供用户选择。若用户选择后则一直使用那个Intent进行接收
    4、若App需要每次用户都进行选择(如:分享)则需要创建IntentChooser来建立
    Intent chooser = Intent.createChooser(intent, title);

    二、获取调用Activity的返回结果

    1、当从Activity返回结果是会回调onActivityResult()方法。想要获取相应数据首先要检查RequestCode
    再检查ResultCode,再获取数据
    2、如何读取联系人

    private void pickContact() {
        Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts");
        pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
        startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == PICK_CONTACT_REQUEST) {
            if (resultCode == RESULT_OK) {
                Uri contactUri = data.getData();
                String[] projection = {Phone.NUMBER};
                // Consider using CursorLoader to perform the query.
                Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null);
                cursor.moveToFirst();
                int column = cursor.getColumnIndex(Phone.NUMBER);
                String number = cursor.getString(column);
            }
        }
    }
    

    三、被调用的Activity如何返回结果

    1、当其他Activity调用的时候被调用的Actvity要定义IntentFilter来相应的Activity
    1)定义Action action为字符串,调用者必须设置Action
    2) 定义Data data通常分为两部分 一部分为uri 二部分为MIMType。 可以不定义,也可以指定义一部分
    3)定义Category 当Activity定义了Action的时候必须显示的定义 一般为android.intent.category.DEFAULT

    <activity android:name="ShareActivity">
        <!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
        <intent-filter>
            <action android:name="android.intent.action.SENDTO"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:scheme="sms" />
            <data android:scheme="smsto" />
        </intent-filter>
        <!-- filter for sending text or images; accepts SEND action and text or image data -->
        <intent-filter>
            <action android:name="android.intent.action.SEND"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:mimeType="image/*"/>
            <data android:mimeType="text/plain"/>
        </intent-filter>
    </activity>

    2、如何返回结果

    Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"));
    setResult(Activity.RESULT_OK, result);
    finish();

    >

    展开全文
  • html和activity之间交互

    2017-09-20 17:42:13
    WebSettings settings = webView.getSettings(); if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.LOLLIPOP) { settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);...
    WebSettings settings = webView.getSettings(); 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
     settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);//为了https
     }
    settings.setJavaScriptEnabled(true);
    
    webView.addJavascriptInterface(WebActivity.this, "web");
    webView.loadUrl("file:///android_asset/demo.html");
    webView.setWebViewClient(new WebViewClient() {//html页面加载完传值过去这样才有效
        @Override
        public void onPageFinished(WebView view, String url) {//当页面加载完成
            super.onPageFinished(view, url);
    
            webView.loadUrl("javascript:setPlain('" + mPlain + "')");//调用html里面的function
            webView.loadUrl("javascript:setSignature('" + mSignature.replaceAll("\r\n", "") + "')");
            webView.loadUrl("javascript:submitUrl()");//调用html里面的function 提交了表单
    
    
        }
    
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            handler.proceed(); // 接受网站证书
        }
    
    });
    @JavascriptInterface 
    public void orderComplete() 
    {//html调到activity}
    
    //html
    <script type="text/javascript"> 
     function setPlain(plain){ document.getElementById("plain").value = plain; } 
    function setSignature(signature){ document.getElementById("signature").value = signature; } 
    function submitUrl(){ document.getElementById("form").submit(); } </script>
    <body>
    <!--<form id="form" action="http://127.0.0.1:8003/paygate/main" method="post">-->  
    <!--<input type="hidden" id="plain" name="Plain">--> 
     <!--<input type="hidden" id="signature" name="Signature">--> <!--</form>-->
    </body>

     

     

     

     

     

    展开全文
  • 一、基础知识: ... Component name 指定启动的Activity  2. Action 要做什么  3. Data 传送数据  4. Category  5. Extras 键值对  6. Flags  2.Intent基本用法:  [java] view plain
  • 两个Activity界面之间进行交互

    千次阅读 2018-11-17 21:31:05
    0,先确定有几个Activity界面。 1,创建两个活动Activity1和Activity2 每个活动: a:extends Activity b:重写onCreate方法(敲上onCreate自动补齐) c:res/layout中建立layout文件(没有layout文件夹,...
  • Android开发adapter与Activity交互

    千次阅读 2017-04-24 00:44:41
    最早的时候我是用Activity实例传递来操作的,或者直接拿 Activity实例来操作(FansActivity.instance = this)  后面我发现这不科学,比如对象回收了呢,或者有些属性不在这个对象里面呢,或者你一直引用,不释放...
  • 自定义Dialog且实现与Activity交互

    千次阅读 2016-07-19 15:43:37
    自定义一个Dialog,其中包含RadioGroup、RadioButton、EditText、Button。Activity 给Dialog传入数据,Activity能获得Dialog的数据,实现了Activity与Dialog的交互
  • 其中,fragment与Activity通信就是一个。 fragment与Activity通信主要是两点: 1、fragment传递信息给Activity 此点是通过在fragment中定义接口与Activity共享数据。 2、Activity传递信息给fragment 此点主要是通过...
  • flutter/kotlin/Android 项目 官方代码: ...重点 MainAcvity 进入Android MainActivity 修改继承,MainActivity() : Activity(), manifest文件中,需改mainActiity主题...
  • Android进阶之Fragment与Activity之间的数据交互

    万次阅读 多人点赞 2016-12-28 11:24:01
    2 参考链接Activity和Fragment传递数据的两种方式【Fragment精深系列4】Fragment与Activity之间的数据交互2 Activity把值传递给Fragment2.1 第一种方式,也是最常用的方式,就是使用Bundle来传递参数(1)宿主...
  • Service与多个Activity交互

    千次阅读 2015-08-28 12:00:19
    Service通过Broadcast与多个Activity进行交互
  • andorid service activity交互方式

    千次阅读 2013-11-11 18:16:15
    android service与activity交互的方试 1:android通过Handler与activity交互 这个实现起来比较简单,只需要把handler传递给service然后通过handler的handleMessage来更新界面就可以了,没什么难点。 我们来看看...
  • Fragment与Activity交互

    千次阅读 2014-05-05 18:30:30
    Activity直接影响它所包含的Fragment的生命周期,所以对Activity的某个生命周期方法的调用也会产生对Fragment相同...Fragment比Activity还要多出几个生命周期回调方法,这些额外的方法是为了与activity交互而设立的。
  • 这里我不再详细介绍那写比较chang gui
  • Service Activity三种交互方式

    万次阅读 2012-09-09 22:52:44
    service有两种类型:  本地服务(Local Service... 前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。  后者可被其他
  • 首先我们来介绍使用Handler来实现Fragment与Activity交互。 第一步,我们需要在Activity中定义一个方法用来设置Handler对象。 public void setHandler(Handler handler) { mHandler = handler; } 第二步,在...
  • fragment与activity交互时生命周期顺序

    千次阅读 2013-10-11 18:33:03
    fragment加入到activity过程中,经历了一下生命周期:  fragment的onAttach() fragment的onCreate() fragment的onCreateView() Activity的onCreate() fragment的onActivityCreated() activity的onstart()...
  • Service跟Activity是最相似的组件,都代表可执行的程序,区别在于:Service一直在后台运行,没有跟用户交互的界面。 启动与停止Service有两种方法: 第一种通过startService()与stopService()启动和停止服务,...
  • 1概念 1 为什么 因为Fragment和Activity一样是具有生命周期,不是一般的bean通过构造函数传值,会造成异常。...【Fragment精深系列4】Fragment与Activity之间的数据交互 2 Activity把值传递...

空空如也

1 2 3 4 5 ... 20
收藏数 102,506
精华内容 41,002
关键字:

activity交互