def extract_relationship_for_app(apk_address):
    method_pattern='^.method'
    end_method_pattern='^.end\smethod'
    app_name_pattern='.+apk/.+/(.+)'
    new_line_pattern='[\r\n]'
    target_line_pattern='\s+invoke-.+'
    invoke_method_pattern='.+(invoke-(direct|static|virtual|super|interface)).+'
    package_pattern=', (.+)->'
    API_call_pattern=', (.+);'
    
#app_smali_folder_dir 
    API_invoke_methods=defaultdict(list)
    API_package=defaultdict(list)
    app_API=defaultdict(list)
    API_codeblocks=[]
    for cat in os.listdir(apk_address):
        cat_dir=os.path.join(apk_address, cat)
        if os.path.isdir(cat_dir):
            #### for computation, I only take 2
            app_smali_folder_path=[os.path.join(cat_dir, smali_class) for smali_class in os.listdir(cat_dir)\
                                   if not smali_class.endswith('.apk') and os.path.isdir(os.path.join(cat_dir, \
                                                                                                     smali_class))][:2]
            for app_smali_folder_dir in app_smali_folder_path:
                print(app_smali_folder_dir)
                app_name=re.match(app_name_pattern,app_smali_folder_dir).group(1)
                add_line=False
                for dirpath, dirname, files in os.walk(app_smali_folder_dir):
                    for file in files:
                        if file.endswith('.smali'):
                            with open(os.path.join(dirpath, file), 'r+') as auto:
                                with open(auto.name, 'r+') as f:

                                    for i in f.readlines():
                                        new_line=re.match(new_line_pattern, i)
                                        start_method=re.match(method_pattern, i)
                                        end_method=re.match(end_method_pattern, i)
                                        target_line=re.match(target_line_pattern, i)

                                        if new_line:
                                            continue
                                        if start_method:
                                            add_line=True
                                            API_single_codeblock=[]
                                        if end_method:
                                            add_line=False
                                            API_codeblocks.append(API_single_codeblock)
                                        if add_line==True:
                                            #extract invoke method, API calls once the line is target line within the code clocks
                                            if target_line:
                                                #extract invoke_method+package+API calls
                                                #method_type is among 'invoke-static', 'invoke-virtual', 
                                                #'invoke-direct', 'invoke-super', 'invoke-interface'
                                                invoke_method=re.match(invoke_method_pattern, i).group(1)
                                                #find the package after the invoke method
                                                #find the API call

                                                #find the package after the invoke method
                                                try:
                                                    package=re.findall(package_pattern, i)[0]
                                                    API_call=re.findall(API_call_pattern, i)[0]
                                                except:
                                                    print(dirname, file)
                                                    print(target_line.group(0))
                                                    print(package)
                                                    print(API_call)
                                                    pass
                                                #### API-InvokeMethod
                                                if API_call not in API_invoke_methods[invoke_method]:
                                                    API_invoke_methods[invoke_method].append(API_call)
                                                else:
                                                    continue
                                                #### API-package
                                                if API_call not in API_package[package]:
                                                    API_package[package].append(API_call)
                                                else:
                                                    continue
                                                #### API_call in single code block
                                                if API_call not in API_single_codeblock:
                                                    API_single_codeblock.append(API_call)
                                                else:
                                                    continue
                                                #### app-API
                                                app_API[app_name].append(API_call)

                output=[API_package,API_invoke_methods,app_API,API_codeblocks]
                output_name=['API_package', 'API_invoke_methods', 'app_API', 'API_codeblocks']

                for i in range(len(output)):
                    data=output[i]
                    with open('/Users/chensizhu/Desktop/data injection/smali/'+output_name[i]+'.json', 'w') as f:
                        json.dump(data, f)
    return