Рендеринг к единому растровому изображению возражает от нескольких потоков

Несоответствие типов. Требуется: MyUser.UserListViewModel? Найдено: com.example. ***. Ui.MyUser.UserListViewModel

В основном ошибка говорит о том, что ваш

binding.viewModel //is a nullable type and there for it expects a nullable 
//type to be assigned as well

Так что просто превратите вашу модель представления в обнуляемый тип, добавив ? символ после его делакариона (обратите внимание, что поздние типы инициализации не допускают обнуляемые типы). попробуйте вот так

private var viewModel: UserListViewModel? =  null

Что касается библиотеки ошибок связывания второй ошибки, которую нужно скомпилировать, чтобы автоматически сгенерировать класс привязки, просто пересоберите проект, и эта ошибка исчезнет.

Пожалуйста, не стесняйтесь использовать этот шаблон в качестве основы, чтобы избежать всего этого стандартного кода

@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS)
annotation class ContentView(@LayoutRes val id: Int)

fun ViewGroup.inflate(@LayoutRes layoutId: Int,
addContainer: Boolean = false): View {                                                     
    return LayoutInflater.from(context).inflate(layoutId,this,addContainer)      
}

@Suppress("UNCHECKED_CAST")
abstract class BaseFragment<Model : ViewModel, Binding : ViewDataBinding> : Fragment() {
/**
 * Data binding class variable all view elements declared on the
 * Xml file will be available within this instance if a view model
 * Is required for the xml to work we will need to bind it on @onBindViewModel
 */
protected lateinit var binding: WeakReference<Binding?>

/**
 * Fragments view model according to MVVM android architecture
 * Each fragment class should have one , in order to facilitate
 * Live Data and Binding library features, tho we can skip it
 */
protected lateinit var viewModel: WeakReference<Model?>

/**
 * Here is where most likely you will get not null data , both binding and
 * view model references can be destroyed by garbage collector
 * If this application reaches low memory levels
 *
 * This optional method is used to bind the required view model inside the
 * Xml file, this is optional to use tho is recommended
 * Bind them by calling the view model binding.customViewModel = viewModel
 */
protected open fun onBindViewModel(viewModel: Model?, binding: Binding?) {}

/**
 * There will be the occasion where custom params will be needed on view model's
 * Constructor in this case will want to override the default creation @see ViewModelFactory
 */
protected open fun onCreateViewModel(modelType: Class<Model>): Model? = if (modelType != ViewModel::class.java)
    ViewModelProviders.of(requireActivity()).get(modelType) else null

/**
 * Here we will inherit view model and binding values based on the class
 * Parameters and store them in global variables so any class extending
 * From Base activity has access to binding and view model instances by default
 */
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val layout = this.javaClass.annotations.find { it.annotationClass == ContentView::class } as ContentView?
        ?: throw RuntimeException("You annotate this class with @ContentView and provide a layout resource")

    container?.let { binding = WeakReference(DataBindingUtil.bind(it.inflate(layout.id))!!) }
        ?: run { binding = WeakReference(DataBindingUtil.bind(inflater.inflate(layout.id, null))) }

    viewModel = WeakReference(
        onCreateViewModel(
            (this.javaClass.genericSuperclass
                    as ParameterizedType).actualTypeArguments[0] as Class<Model>
        )
    )

    setHasOptionsMenu(true)
    onBindViewModel(viewModel.get(), binding.get())
    return binding.get()?.root
}
}

И просто используйте его вот так (посмотрите, сколько кода на плите пропало)

@ContentView(R.layout.fragment_user)
class UserFragment: BaseFragment<UserListViewModel, FragmentUserBinding> {

override fun onBindViewModel(viewModel: UserListViewModel?, binding: FragmentUserBinding?) {
    binding.viewModel = viewModel
}
}
6
задан Lee Treveil 16 March 2009 в 01:41
поделиться

5 ответов

Lee, если Вы собираетесь использовать Изображение GDI + объект, можно только закончить тем, что делали всю работу дважды. Разделы, которые Вы генерируете в нескольких потоках, должны будут быть повторно собраны в конце Вашего деления и завоевать подход и разве который не победил бы цель разделиться во-первых?

Эта проблема могла бы только быть преодолена при выполнении чего-то довольно сложного в каждом из растровых разделов, которые были бы намного большим количеством времени обработки, чем простая перерисовка подразделений изображения на большой битовый массив, не идя во всю ту проблему.

Надежда, которая помогает. Какой рендеринг изображения Вы распланировали?

1
ответ дан 17 December 2019 в 04:52
поделиться

Вы могли использовать LockBits и работать над отдельными разделами изображения.

Для примера того, как это сделано, можно посмотреть на Краску. Сетевой исходный код, особенно BackgroundEffectsRenderer (да, который является ссылкой на моно ответвление, но Краской. Сетевой основной код, кажется, только доступен в zip-файлах).

4
ответ дан 17 December 2019 в 04:52
поделиться

У Вас могла быть каждая запись потока к массиву байтов, затем когда они все закончены, используйте единственный поток для создания растрового объекта из массивов байтов. Если вся другая обработка была сделана перед рукой, которая должна быть довольно быстрой.

0
ответ дан 17 December 2019 в 04:52
поделиться

Я сделал что-то подобное, и в моем случае у меня была каждая блокировка потока x (зависел от размера изображения и количества потоков), много строк битов в изображении, и делайте их записи к тем битам, таким образом, что никакие потоки никогда не перекрывали свои записи.

0
ответ дан 17 December 2019 в 04:52
поделиться

Один из подходов - отрендерить все маленькие растровые изображения в растровое изображение эрзац , которое будет просто двумерным массивом int (который является своего рода Bitmap действительно есть). После того, как все маленькие растровые изображения объединены в большой массив, вы делаете единовременное копирование из большого массива в реальное Bitmap тех же размеров.

Я все время использую этот подход (не включая многопоточность) для сложной графики на устройствах Windows Mobile, поскольку память, доступная для создания «настоящих» растровых изображений GDI +, сильно ограничена.

Вы также можете просто использовать Bitmap , как вы изначально планировали. Bitmap не гарантируется поточно-ориентированной, но я не уверен, что это будет проблемой, если вы можете быть уверены, что никакие два потока никогда не перезаписывают одну и ту же часть растрового изображения. По крайней мере, я бы попробовал.

Обновление: Я только что перечитал ваш вопрос и понял, что вы, вероятно, не увидите большого (если таковое имеется) улучшения общей скорости этих операций, если сделаете их многопоточными. Это классическая проблема девяти женщин, которые не могут зачать ребенка за месяц.

0
ответ дан 17 December 2019 в 04:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: