【问题标题】:How to avoid spaghetti code in Android by Moving code in new Classes (Kotlin)如何通过在新类中移动代码(Kotlin)来避免 Android 中的意大利面条代码
【发布时间】:2019-12-17 13:55:09
【问题描述】:

从下面的主类中,我试图将尽可能多的代码移动到 2 个分别名为“PhotoCapture.kt”和“PhotoUpload.kt”的新类文件中。我找不到让它工作的方法。看起来我只能在 MainActivity 中工作。例如,我找不到在新类中移动方法“onActivityResult”的方法。为了了解整个事情的运作方式,我还需要了解什么?

谢谢朋友们!

package com.tabapab.takepictureandsave

import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.support.v4.content.FileProvider
import android.util.Log
import android.util.Base64
import android.widget.ImageView
import com.android.volley.AuthFailureError
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import kotlinx.android.synthetic.main.activity_main.*
import org.json.JSONObject
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*


class MainActivity : AppCompatActivity() {
    var namaFile = ""
  //  var fileUri = Uri.parse("")
    val RC_CAMERA = 100

    val REQUEST_TAKE_PHOTO = 1001

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        capture_btn.setOnClickListener {
            dispatchTakePictureIntent()
        }
    }

    private fun dispatchTakePictureIntent() {
        Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
            // Ensure that there's a camera activity to handle the intent
            takePictureIntent.resolveActivity(packageManager)?.also {
                // Create the File where the photo should go
                val photoFile: File? = try {
                    createImageFile()
                } catch (ex: IOException) {
                    // Error occurred while creating the File

                    null
                }
                // Continue only if the File was successfully created
                photoFile?.also {
                    val photoURI: Uri = FileProvider.getUriForFile(
                            this,
                            "com.tabapab.takepictureandsave",
                            it
                    )
                    takePictureIntent.putExtra(MediaStore.ACTION_IMAGE_CAPTURE, photoURI)
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
                    startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO)
                }
            }
        }
    }

    lateinit var currentPhotoPath: String

    @Throws(IOException::class)
    private fun createImageFile(): File {
        // Create an image file name
        val timeStamp: String = SimpleDateFormat("ddMMyyyy_HHmmss").format(Date())
        val storageDir: File = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        val filNam = File.createTempFile(
                "JPEG_${timeStamp}_", /* prefix */
                ".jpg", /* suffix */
                storageDir /* directory */
        ).apply {
            // Save a file: path for use with ACTION_VIEW intents
            currentPhotoPath = absolutePath
        }
        Log.d("myDebug", storageDir.toString())
        return filNam
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
            //   val imageBitmap = data.extras.get("data") as Bitmap
            // image_view.setImageBitmap(imageBitmap)
            // galleryAddPic()
            val f = File(currentPhotoPath)
            Log.d("myDebug", currentPhotoPath)
       //     image_view.setImageURI(Uri.fromFile(f)) // this sets uncompressed,
        val imgStr =  getBitmapToString(image_view, Uri.fromFile(f))
            volleyImg(imgStr)
        }
    }

    fun bitmapToString(bmp: Bitmap): String {
        val outputStream = ByteArrayOutputStream()
        bmp.compress(Bitmap.CompressFormat.JPEG, 60, outputStream)
        val byteArray = outputStream.toByteArray()
        return Base64.encodeToString(byteArray, Base64.DEFAULT)


    }

    fun getBitmapToString(imV: ImageView, Fileuri: Uri): String {
            var bmp = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888)
            bmp = BitmapFactory.decodeFile(Fileuri.path)
            Log.d("myDebug", Fileuri.path)
            var dim = 720
            Log.d("myDebug", "height:" + bmp.height + " _width:"+ bmp.width)
            if (bmp.height > bmp.width) {
                bmp = Bitmap.createScaledBitmap(bmp,
                        (bmp.width*dim).div(bmp.height), dim, true)
            } else {
                bmp = Bitmap.createScaledBitmap(bmp,
                        dim, (bmp.height*dim).div(bmp.width), true)
            }
            imV.setImageBitmap(bmp)
            return bitmapToString(bmp)
            return ""
    }

    private fun volleyImg(imgStr: String) {

        msg_display.text = "Starting Volley Kick"

        val url:String = "http://192.168.10.6/tabapad1/modules/android/classes/main.php?op=filestr"
        //      val rq:RequestQueue=Volley.newRequestQueue(this)
        val stringRequest = object : StringRequest(Request.Method.POST, url,
                Response.Listener<String> { response ->
                    // Process the json
                    try {
                        val obj = JSONObject(response)
                        msg_display.text = obj.getString("message")
                    } catch (e: Exception) {
                        msg_display.text = "Exception: $e"
                    }

                }, Response.ErrorListener { error ->
            msg_display.text = error.message
        }) {


            @Throws(AuthFailureError::class)
            override fun getParams(): Map<String, String> {
                val params = HashMap<String, String>()
                params.put("filename", "Maria2.jpg")
                params.put("imstr", imgStr)
                msg_display.text = "Sets the Volley parameters"
                return params

            }

        }
        // Add the volley post request to the request queue
        VolleySingleton.getInstance(this).addToRequestQueue(stringRequest)


        //    rq.add(request)


    }


//    private fun galleryAddPic() {
//        // run this to add the photo to system's Media Provider's database
//        // It will be available in the Android Gallery application and other Apps
//        Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).also { mediaScanIntent ->
//            val f = File(currentPhotoPath)
//            mediaScanIntent.data = Uri.fromFile(f)
//            sendBroadcast(mediaScanIntent)
//        }
//    }


}

【问题讨论】:

    标签: android android-studio kotlin android-activity android-appcompat


    【解决方案1】:

    您不能将onActivityResult 移动为it's tied with startActivityForResult。您正在启动使用本机相机拍照的意图,并且您的活动正在期待结果。结果返回到最初启动意图的活动。

    通常,您可以从活动中删除方法/功能,当它们的使用可以应用于其他各种地方时。例如,您的 bitmapToString 函数可以轻松放入 Utils 类中,因为它接收通用变量并且具有不依赖于活动的任何其他部分的主体。通过一些更改,也可以提取其他功能。例如,如果您将文件名变量作为参数添加到createImageFile(),您可以在其他活动中使用该变量,这些活动不一定希望与此处使用的文件名格式相同。

    【讨论】:

    • 谢谢你。我想我的代码将在片段类中运行。我的意思是从 AppCompatActivity() 扩展的类具有与从 Fragment() 扩展的类相同的方法?有什么区别?
    • @Thanasis Activity 是主要的 Android 组件之一。片段是特定行为的表示。您可以有没有片段的活动,但不能有没有至少一个活动的片段。尽管它们有很多共同的功能,但也有很多不能同时包含在两者中。关于何时使用活动与片段(stackoverflow.com/questions/20306091/…)有很多讨论。请查看开发人员指南以获取更多信息:developer.android.com/guide/components/activities/…
    • 尽管阅读和搜索了一些问题,但我并不清楚。谢谢您的帮助。最后一件事。是否可以将我的上述代码重定向到新活动?但是将 setContentView(R.layout.activity_main) 留给 mainActivity 并从 mainActivity 类调用另一个活动(类)。新的类/活动不会调用 view.xml ( setContentView ),而只会容纳我的代码。可能吗。好的,我会尝试阅读更多内容,但我无法在任何地方得到答案。谢谢。
    • @Thanasis 活动往往有自己的 UI,因为它们主要负责用户看到和与之交互的内容。如果您想在同一用户界面(您称为 view.xml)中创建某些功能或特性,您可以委托您的功能并将它们组织在类中,并让您的活动调用它们以获取结果,然后将它们呈现给用户.当一个函数在 Kotlin 中公开时,您可以从任何地方调用它。从这个意义上说,您可以在不设置新内容视图的情况下拥有您的主要活动并从其他类调用函数。
    • @Thanasis 我赞成你的问题,但已经有人反对,因此你现在是 0。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多